### TRMNL Success Webhook Body
Source: https://docs.usetrmnl.com/go/plugin-marketplace/plugin-installation-flow
This is an example of the JSON payload sent by TRMNL to the `installation_success_webhook_url` upon successful plugin installation. It contains user details such as name, email, locale, timezone, and a unique `plugin_setting_id` which is crucial for redirecting users back to specific plugin settings.
```json
{
"user": {
"name":"Ronak J",
"email":"ronak@usetrmnl.com",
"first_name":"Ronak",
"last_name":"J",
"locale":"en",
"time_zone":"Pacific Time (US & Canada)",
"time_zone_iana":"America/Los_Angeles",
"utc_offset":-28800,
"plugin_setting_id":1234,
"uuid": "674c9d99-cea1-4e52-9025-9efbe0e30901"
}
}
```
--------------------------------
### Basic TRMNL Plugin HTML Structure (No Account)
Source: https://docs.usetrmnl.com/go/private-plugins/templates
This HTML structure demonstrates a 'full' layout plugin for TRMNL devices, including necessary CSS and JS links. It showcases basic markdown rendering for quotes and includes a title bar. This serves as a starting point for users without a TRMNL account.
```erb
Motivational Quote
“I love inside jokes. I hope to be a part of one someday.”
Michael Scott
Plugin TitleInstance Title
```
--------------------------------
### Render an Un-styled Line Chart with Highcharts
Source: https://docs.usetrmnl.com/go/private-plugins/templates-advanced
This snippet demonstrates how to create a basic line chart using the Highcharts JavaScript library. It includes the necessary script tags for Highcharts and Chartkick, and then configures a simple line chart with specified data and axis types. This example is intended for initial setup before applying custom TRMNL styling.
```html
```
--------------------------------
### Token Exchange API
Source: https://docs.usetrmnl.com/go/plugin-marketplace/plugin-installation-flow
After receiving an installation request, your server must exchange the provided code for an access token using this endpoint.
```APIDOC
## POST /oauth/token
### Description
Exchanges an authorization code for an access token.
### Method
POST
### Endpoint
`https://usetrmnl.com/oauth/token`
### Parameters
#### Request Body
- **code** (string) - Required - The authorization code received from the installation request.
- **client_id** (string) - Required - Your plugin's client ID.
- **client_secret** (string) - Required - Your plugin's client secret.
- **grant_type** (string) - Required - Must be set to `"authorization_code"`.
### Request Example
```json
{
"code": "code-from-step-1",
"client_id": "your-plugin-client-id",
"client_secret": "your-plugin-secret",
"grant_type": "authorization_code"
}
```
### Response
#### Success Response (200)
- **access_token** (string) - The access token for authenticating subsequent requests.
#### Response Example
```json
{
"access_token": ""
}
```
```
--------------------------------
### Installation Success Webhook
Source: https://docs.usetrmnl.com/go/plugin-marketplace/plugin-installation-flow
TRMNL sends a notification to this endpoint after a user successfully installs your plugin.
```APIDOC
## POST /installation/success
### Description
Receives a success notification when a user completes plugin installation.
### Method
POST
### Endpoint
`installation_success_webhook_url` (provided in the initial installation request)
### Parameters
#### Request Headers
- **Authorization** (string) - Required - Bearer token: `"Bearer "`.
- **Content-Type** (string) - Required - Must be `"application/json"`.
#### Request Body
- **user** (object) - Required - Information about the user.
- **name** (string) - User's full name.
- **email** (string) - User's email address.
- **first_name** (string) - User's first name.
- **last_name** (string) - User's last name.
- **locale** (string) - User's locale.
- **time_zone** (string) - User's time zone name.
- **time_zone_iana** (string) - User's IANA time zone identifier.
- **utc_offset** (integer) - User's UTC offset in seconds.
- **plugin_setting_id** (integer) - The unique ID for this plugin's settings for the user. Useful for redirect URIs.
- **uuid** (string) - User's unique identifier.
### Response Example
```json
{
"user": {
"name": "Ronak J",
"email": "ronak@usetrmnl.com",
"first_name": "Ronak",
"last_name": "J",
"locale": "en",
"time_zone": "Pacific Time (US & Canada)",
"time_zone_iana": "America/Los_Angeles",
"utc_offset": -28800,
"plugin_setting_id": 1234,
"uuid": "674c9d99-cea1-4e52-9025-9efbe0e30901"
}
}
```
```
--------------------------------
### Setup API
Source: https://docs.usetrmnl.com/go/diy/byos
This endpoint is used to set up a device. It requires a device MAC address in the ID header.
```APIDOC
## POST /api/setup
### Description
This endpoint is used to set up a device. It requires a device MAC address in the ID header.
### Method
POST
### Endpoint
/api/setup
### Parameters
#### Headers
- **ID** (string) - Required - The MAC address of the device.
- **Content-Type** (string) - Required - application/json
### Request Example
```shell
curl "https://byos.local/api/setup" \
-H 'ID: ' \
-H 'Content-Type: application/json'
```
### Response
#### Success Response (200)
- **status** (string) - Indicates the success or failure of the setup operation.
#### Response Example
```json
{
"status": "success"
}
```
```
--------------------------------
### TRMNL Success Webhook Headers
Source: https://docs.usetrmnl.com/go/plugin-marketplace/plugin-installation-flow
When a user successfully installs a plugin, TRMNL sends a success notification. This example shows the required HTTP headers for this notification, which include an 'Authorization' header with a Bearer token and a 'Content-Type' header set to 'application/json'.
```json
{ 'Authorization': 'Bearer ', 'Content-Type': 'application/json' }
```
--------------------------------
### Get Devices API Example Response (JavaScript)
Source: https://docs.usetrmnl.com/go/private-api/account
This snippet shows an example JSON response from the TRMNL Account API when requesting a list of devices. It details the structure of the device data, including ID, name, MAC address, and battery status. This response format is crucial for clients interacting with the API.
```javascript
// GET https://usetrmnl.com/api/devices
{
"data": [
{
"id": 123456,
"name": "My TRMNL",
"friendly_id": "A1B2C3",
"mac_address": "AB:CD:EF:12:34:56",
"battery_voltage": 3.9,
"rssi": -41
}
]
}
```
--------------------------------
### Account API - Device Endpoint Example
Source: https://docs.usetrmnl.com/go/private-api/account
This example demonstrates how to retrieve a list of your TRMNL devices using the Account API.
```APIDOC
## GET /api/devices
### Description
Retrieves a list of all TRMNL devices associated with your account.
### Method
GET
### Endpoint
/api/devices
### Parameters
None
### Request Example
None
### Response
#### Success Response (200)
- **data** (array) - An array of device objects.
- **id** (integer) - The unique identifier for the device.
- **name** (string) - The name of the device.
- **friendly_id** (string) - A user-friendly identifier for the device.
- **mac_address** (string) - The MAC address of the device.
- **battery_voltage** (float) - The current battery voltage of the device.
- **rssi** (integer) - The Received Signal Strength Indicator of the device.
#### Response Example
```json
{
"data": [
{
"id": 123456,
"name": "My TRMNL",
"friendly_id": "A1B2C3",
"mac_address": "AB:CD:EF:12:34:56",
"battery_voltage": 3.9,
"rssi": -41
}
]
}
```
```
--------------------------------
### Setup TRMNL Device via API
Source: https://docs.usetrmnl.com/go/diy/byos
This snippet demonstrates how to set up a TRMNL device using the API. It requires the device's MAC address in the 'ID' header and specifies JSON content type. The endpoint is '/api/setup'.
```shell
curl "https://byos.local/api/setup" \
-H 'ID: ' \
-H 'Content-Type: application/json'
```
--------------------------------
### TRMNL Display API Response Example (JSON)
Source: https://docs.usetrmnl.com/go/diy/byod-s
This is an example of the JSON response returned by the TRMNL Display API when a device pings it. It contains the absolute URL of the next image in the queue.
```json
{
"image_url":"https://trmnl.s3.us-east-2.amazonaws.com/path-to-img.png"
}
```
--------------------------------
### Fetch Access Token from TRMNL (Ruby)
Source: https://docs.usetrmnl.com/go/plugin-marketplace/plugin-installation-flow
This snippet demonstrates how to request an access token from TRMNL's OAuth endpoint. It requires the `code` received in the initial installation request, along with your plugin's `client_id`, `client_secret`, and the `grant_type` set to 'authorization_code'. The response will contain the `access_token`.
```ruby
body = {
code: 'code-from-step-1',
client_id: 'your-plugin-client-id',
client_secret: 'your-plugin-secret',
grant_type: 'authorization_code'
}
response = HTTParty.post("https://usetrmnl.com/oauth/token", body: body)
response['access_token']
```
--------------------------------
### Get Single Recipe Details (JSON Response)
Source: https://docs.usetrmnl.com/go/public-api/recipes-api
This snippet displays the structure of a successful JSON response when retrieving a single recipe. It includes recipe metadata such as name, URLs, author information, custom fields, and statistics. This format is used as a standard output for the GET /recipes/{id}.json API call.
```json
{
"data": {
"id": 16382,
"name": "Matrix",
"published_at":"2025-02-10T11:33:00.000Z",
"icon_url": "https://trmnl-public.s3.us-east-2.amazonaws.com/mtpxyr22spnwjheeh5kv1p7tpk6n",
"screenshot_url": "https://trmnl.s3.us-east-2.amazonaws.com/jly9u094jtsc2bwmnhlnmwjnsokk?response-content-disposition=inline%3B%20filename%3D%22plugin-2025-04-10T12-47-23Z-776f51%22%3B%20filename%2A%3DUTF-8%27%27plugin-2025-04-10T12-47-23Z-776f51&response-content-type=image%2Fbmp&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIA47CRUQUU4VKBBMOF%2F20251024%2Fus-east-2%2Fs3%2Faws4_request&X-Amz-Date=20251024T210933Z&X-Amz-Expires=300&X-Amz-SignedHeaders=host&X-Amz-Signature=828e75fc333464c3ba13654c70434d307a8ca48053cd102f4a10a55e953c3ce2",
"author_bio": {
"keyname": "doesnt_matter",
"name": "About This Plugin",
"field_type": "author_bio",
"description": "Matrix brings the iconic digital rain from the movies to your screen. By default, it displays the current date in the classic style, but you can also customize it to show any message you want.",
"category": "calendar,life"
},
"custom_fields": [
{
"keyname": "doesnt_matter",
"name": "About This Plugin",
"field_type": "author_bio",
"description": "Matrix brings the iconic digital rain from the movies to your screen. By default, it displays the current date in the classic style, but you can also customize it to show any message you want.",
"category": "calendar,life"
},
{
"keyname": "message",
"field_type": "string",
"name": "Message",
"default": "%date",
"help_text": "%date to display current date"
}
],
"stats": {
"installs": 25,
"forks": 176
}
}
}
```
--------------------------------
### TRMNL Device API: GET Display Endpoint
Source: https://docs.usetrmnl.com/go/private-api/introduction
This snippet demonstrates how to make a GET request to the TRMNL device's display endpoint. It shows example request headers including 'ID' and 'Access-Token', and the expected JSON response body containing 'image_url', 'filename', and 'update_firmware' fields. This endpoint is used to retrieve content for the device.
```HTTP
GET /api/display
# request headers example
{
'ID' => 'XX:XX:XX:XX',
'Access-Token' => '2r--SahjsAKCFksVcped2Q'
}
# response body example
{
"image_url"=>"https://trmnl.s3.us-east-2.amazonaws.com/path-to-img.bmp",
"filename"=>"2025-05-10-plugin-T00:00:00",
"update_firmware"=>false
}
```
--------------------------------
### Server Request Example for TRMNL Plugin
Source: https://docs.usetrmnl.com/go/plugin-marketplace/plugin-screen-generation-flow
This snippet demonstrates how TRMNL sends a POST request to a plugin's markup URL to fetch screen content. It includes the authorization header and form-urlencoded data containing user UUID and metadata. Ensure your server is configured to accept and process this request.
```bash
curl -XPOST 'https://your-server.com/your-markup-url' \
-H 'Authorization: Bearer xxx' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'user_uuid=xx&trmnl='
```
--------------------------------
### GET /recipes/{id}.json
Source: https://docs.usetrmnl.com/go/public-api/recipes-api
Retrieves detailed information about a single recipe by its ID. This endpoint is useful for displaying recipe details on a webpage or in an application.
```APIDOC
## GET /recipes/{id}.json
### Description
Retrieves detailed information about a single recipe by its ID. This endpoint is useful for displaying recipe details on a webpage or in an application.
### Method
GET
### Endpoint
`/recipes/{id}.json`
#### Path Parameters
- **id** (integer) - Required - The unique identifier of the recipe.
### Request Example
`https://usetrmnl.com/recipes/16382.json`
### Response
#### Success Response (200)
- **data** (object) - Contains the recipe details.
- **id** (integer) - The unique identifier of the recipe.
- **name** (string) - The name of the recipe.
- **published_at** (string) - The date and time when the recipe was published (ISO 8601 format).
- **icon_url** (string) - URL to the recipe's icon.
- **screenshot_url** (string) - URL to a screenshot of the recipe.
- **author_bio** (object) - Information about the author.
- **keyname** (string)
- **name** (string)
- **field_type** (string)
- **description** (string)
- **category** (string)
- **custom_fields** (array) - An array of custom fields associated with the recipe.
- Each element is an object with properties like **keyname**, **name**, **field_type**, **default**, **help_text**, **description**, and **category**.
- **stats** (object) - Statistics related to the recipe.
- **installs** (integer) - Number of installs.
- **forks** (integer) - Number of forks.
#### Response Example
```json
{
"data": {
"id": 16382,
"name": "Matrix",
"published_at": "2025-02-10T11:33:00.000Z",
"icon_url": "https://trmnl-public.s3.us-east-2.amazonaws.com/mtpxyr22spnwjheeh5kv1p7tpk6n",
"screenshot_url": "https://trmnl.s3.us-east-2.amazonaws.com/jly9u094jtsc2bwmnhlnmwjnsokk?response-content-disposition=inline%3B%20filename%3D%22plugin-2025-04-10T12-47-23Z-776f51%22%3B%20filename%2A%3DUTF-8%27%27plugin-2025-04-10T12-47-23Z-776f51&response-content-type=image%2Fbmp&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIA47CRUQUU4VKBBMOF%2F20251024%2Fus-east-2%2Fs3%2Faws4_request&X-Amz-Date=20251024T210933Z&X-Amz-Expires=300&X-Amz-SignedHeaders=host&X-Amz-Signature=828e75fc333464c3ba13654c70434d307a8ca48053cd102f4a10a55e953c3ce2",
"author_bio": {
"keyname": "doesnt_matter",
"name": "About This Plugin",
"field_type": "author_bio",
"description": "Matrix brings the iconic digital rain from the movies to your screen. By default, it displays the current date in the classic style, but you can also customize it to show any message you want.",
"category": "calendar,life"
},
"custom_fields": [
{
"keyname": "doesnt_matter",
"name": "About This Plugin",
"field_type": "author_bio",
"description": "Matrix brings the iconic digital rain from the movies to your screen. By default, it displays the current date in the classic style, but you can also customize it to show any message you want.",
"category": "calendar,life"
},
{
"keyname": "message",
"field_type": "string",
"name": "Message",
"default": "%date",
"help_text": "%date to display current date"
}
],
"stats": {
"installs": 25,
"forks": 176
}
}
}
```
```
--------------------------------
### Plugin Management Redirection
Source: https://docs.usetrmnl.com/go/plugin-marketplace/plugin-management-flow
When a user installs a plugin, TRMNL redirects them to the `plugin_management_url`. This URL will include a `uuid` query parameter, which is a unique identifier for the user within the TRMNL plugin architecture. This allows your application to identify and manage settings for specific user instances of the plugin.
```APIDOC
## GET /manage
### Description
Redirects the user to the plugin management URL with a unique user identifier (UUID).
### Method
GET
### Endpoint
`https://yourapp.com/manage?uuid={uuid}`
### Query Parameters
- **uuid** (string) - Required - A unique identifier for the user within the TRMNL plugin architecture.
### Request Example
`https://yourapp.com/manage?uuid=ae48d6ac-48f4-4aed-8464-bad68368e97c`
### Response
#### Success Response (302 Found)
Redirects to the provided `plugin_management_url` with the `uuid` parameter.
```
--------------------------------
### POST /plugins/my/new
Source: https://docs.usetrmnl.com/go/plugin-marketplace/plugin-creation
Create a new plugin by submitting its details and relevant URLs.
```APIDOC
## POST /plugins/my/new
### Description
This endpoint allows you to create a new plugin for the TRMNL platform. You need to provide comprehensive information about your plugin, including its name, description, icon, and various URLs for installation, management, and event handling.
### Method
POST
### Endpoint
https://usetrmnl.com/plugins/my/new
### Parameters
#### Request Body
- **Name** (string) - Required - A branded title or a brief tag describing the plugin's functionality.
- **Description** (string) - Required - Additional text to help differentiate your plugin.
- **Icon** (file) - Optional - Preferred format is PNG.
- **Installation URL** (string) - Required - The endpoint where TRMNL should trigger the installation flow.
- **Installation Success Webhook URL** (string) - Required - The URL where TRMNL should send installation success events.
- **Plugin Management URL** (string) - Required - The URL where TRMNL users can manage their plugins.
- **Plugin Markup URL** (string) - Required - The endpoint where TRMNL should ping your webserver for markup content.
- **Uninstallation Webhook URL** (string) - Required - The URL where TRMNL should send uninstallation events.
### Request Example
```json
{
"Name": "Example Plugin",
"Description": "This is an example plugin for demonstration purposes.",
"Installation URL": "https://example.com/install",
"Installation Success Webhook URL": "https://example.com/webhook/install-success",
"Plugin Management URL": "https://example.com/manage",
"Plugin Markup URL": "https://example.com/markup",
"Uninstallation Webhook URL": "https://example.com/webhook/uninstall"
}
```
### Response
#### Success Response (201 Created)
- **message** (string) - A confirmation message indicating successful plugin creation.
- **pluginId** (string) - The unique identifier for the newly created plugin.
#### Response Example
```json
{
"message": "Plugin created successfully.",
"pluginId": "plg_abcdef123456"
}
```
#### Error Response (400 Bad Request)
- **error** (string) - A message describing the validation error (e.g., missing required fields).
#### Error Response Example
```json
{
"error": "Missing required field: Name"
}
```
```
--------------------------------
### Reusable Liquid Templates
Source: https://docs.usetrmnl.com/go/reusing-markup
Shows how to define and render custom Liquid templates (partials or components) for reusing markup chunks. The `{% template %}` tag defines a template, and `{% render %}` tag uses it.
```liquid
{% template say_hello %}
Hello there, {{ name }}.
{% endtemplate %}
{% render "say_hello", name: "General Kenobi" %}
```
--------------------------------
### Get Merge Variable Content
Source: https://docs.usetrmnl.com/go/private-plugins/webhooks
Fetch existing `merge_variables` from a private plugin by sending a GET request to the same webhook endpoint.
```APIDOC
## GET /api/custom_plugins/{plugin_uuid}
### Description
Retrieves the current `merge_variables` content stored within a private plugin.
### Method
GET
### Endpoint
`https://usetrmnl.com/api/custom_plugins/{plugin_uuid}`
### Parameters
#### Path Parameters
- **plugin_uuid** (string) - Required - The unique identifier for the private plugin.
### Response
#### Success Response (200)
- **merge_variables** (object) - An object containing the current key-value pairs stored in the plugin.
#### Response Example
```json
{
"merge_variables": {
"text": "You can do it!",
"author": "Rob Schneider"
}
}
```
```
--------------------------------
### Get Merge Variable Content via Webhook (cURL)
Source: https://docs.usetrmnl.com/go/private-plugins/webhooks
Fetch existing 'merge_variables' from a private plugin by sending a GET request to the same webhook endpoint. This allows you to retrieve current data stored within the plugin.
```cURL
curl "https://usetrmnl.com/api/custom_plugins/asdfqwerty1234"
```
--------------------------------
### Display API
Source: https://docs.usetrmnl.com/go/diy/byos
This endpoint is used to manage the display settings of a device. It requires a device MAC address in the ID header.
```APIDOC
## GET /api/display
### Description
This endpoint is used to manage the display settings of a device. It requires a device MAC address in the ID header.
### Method
GET
### Endpoint
/api/display
### Parameters
#### Headers
- **ID** (string) - Required - The MAC address of the device.
- **Content-Type** (string) - Required - application/json
### Request Example
```bash
curl "http://byos.local/api/display" \
-H 'ID: ' \
-H 'Content-Type: application/json'
```
### Response
#### Success Response (200)
- **display_settings** (object) - An object containing current display settings.
- **brightness** (integer) - The current brightness level.
- **resolution** (string) - The current display resolution.
#### Response Example
```json
{
"display_settings": {
"brightness": 80,
"resolution": "1920x1080"
}
}
```
```
--------------------------------
### Request a Coupon Code via TRMNL API (POST)
Source: https://docs.usetrmnl.com/go/partners-api/provisioning-devices
This API request is used by partners to initiate the provisioning process by requesting a coupon code. It requires specific headers and a JSON body containing action, data, and metadata. The response includes a unique coupon code if successful, or a nil code if a quota is breached.
```http
POST /api/partners
Headers:
Client-ID, Access-Token # provided by TRMNL team
Body:
{
partner: {
action: "provision_discount",
data: { "user-data": "goes here", "more-data": "also ok" },
meta: { "expires_at": "2025-03-20" } # will expire at 23:59 EST on this date
}
}
# response example
{
status: 200,
data: {
code: "acme-123456789"
}
}
```
--------------------------------
### Shared Markup with CSS in Liquid
Source: https://docs.usetrmnl.com/go/reusing-markup
Demonstrates how to define shared markup, including CSS, that is prepended to every view layout before rendering. This is useful for global styling.
```liquid
Brawndo! It's got what plants crave!
```
--------------------------------
### GET /api/display
Source: https://docs.usetrmnl.com/go/private-api/introduction
Retrieves content information for a TRMNL device. This includes an image URL, a filename, and a flag indicating whether firmware updates are required.
```APIDOC
## GET /api/display
### Description
Retrieves content information such as image URLs and filenames for TRMNL devices. This endpoint can be utilized with or without a physical TRMNL device using an API key.
### Method
GET
### Endpoint
/api/display
### Parameters
#### Request Headers
- **ID** (string) - Required - The unique identifier of the device.
- **Access-Token** (string) - Required - The authentication token for accessing the API.
### Request Example
```json
{
"ID": "XX:XX:XX:XX",
"Access-Token": "2r--SahjsAKCFksVcped2Q"
}
```
### Response
#### Success Response (200)
- **image_url** (string) - The URL of the image content.
- **filename** (string) - The filename associated with the content.
- **update_firmware** (boolean) - Indicates if a firmware update is necessary.
#### Response Example
```json
{
"image_url": "https://trmnl.s3.us-east-2.amazonaws.com/path-to-img.bmp",
"filename": "2025-05-10-plugin-T00:00:00",
"update_firmware": false
}
```
```
--------------------------------
### Set New Content via Webhook
Source: https://docs.usetrmnl.com/go/private-plugins/webhooks
Send a POST request to your Webhook URL to set new content within a private plugin. Data should be placed inside a `merge_variables` node.
```APIDOC
## POST /api/custom_plugins/{plugin_uuid}
### Description
Sets new content or updates existing content within a private plugin using the webhook.
### Method
POST
### Endpoint
`https://usetrmnl.com/api/custom_plugins/{plugin_uuid}`
### Parameters
#### Path Parameters
- **plugin_uuid** (string) - Required - The unique identifier for the private plugin.
#### Request Body
- **merge_variables** (object) - Required - An object containing the key-value pairs to be set or merged.
- **text** (string) - Optional - Example field for text content.
- **author** (string) - Optional - Example field for author information.
- **merge_strategy** (string) - Optional - The strategy to use for merging data. Defaults to 'replace' if not specified. Can be 'deep_merge' or 'stream'.
- **stream_limit** (integer) - Optional - Used with the 'stream' merge strategy to limit the size of arrays.
### Request Example
```json
{
"merge_variables": {
"text": "You can do it!",
"author": "Rob Schneider"
}
}
```
### Response
#### Success Response (200)
- **message** (string) - Confirmation message indicating the content was set.
#### Response Example
```json
{
"message": "Content updated successfully."
}
```
```
--------------------------------
### Google Fonts Integration for TRMNL Plugins
Source: https://docs.usetrmnl.com/go/private-plugins/templates
This snippet shows how to include the 'Inter' font from Google Fonts, which is recommended for achieving the consistent look and feel of TRMNL's in-browser markup editor. It includes preconnect directives for performance.
```html
```
--------------------------------
### POST /api/partners - Request Provisioning Coupon
Source: https://docs.usetrmnl.com/go/partners-api/provisioning-devices
This endpoint allows a partner to request a coupon code for provisioning a device with a custom plugin. The request includes user-specific data and optional metadata like expiration dates. TRMNL generates a unique coupon code based on the provided information.
```APIDOC
## POST /api/partners
### Description
Requests a coupon code for provisioning a device with a custom plugin. This code can be shared with customers for use at checkout.
### Method
POST
### Endpoint
/api/partners
### Parameters
#### Headers
- **Client-ID** (string) - Required - Provided by TRMNL team.
- **Access-Token** (string) - Required - Provided by TRMNL team.
#### Request Body
- **partner** (object) - Required
- **action** (string) - Required - Must be "provision_discount".
- **data** (object) - Required - Contains user-specific data and plugin configuration. The key/values here must match the merge variables required by the plugin setting instance.
- **user-data** (string) - Optional - Example user data.
- **more-data** (string) - Optional - Additional user data.
- **meta** (object) - Optional - Metadata for the coupon.
- **expires_at** (string) - Optional - The date the coupon will expire in YYYY-MM-DD format (e.g., "2025-03-20").
### Request Example
```json
{
"partner": {
"action": "provision_discount",
"data": {
"user-data": "goes here",
"more-data": "also ok"
},
"meta": {
"expires_at": "2025-03-20"
}
}
}
```
### Response
#### Success Response (200)
- **status** (integer) - The status code of the response.
- **data** (object) - Contains the generated coupon code.
- **code** (string) - The generated unique coupon code (e.g., "acme-123456789"). If a quota is breached, this value will be `nil`.
#### Response Example
```json
{
"status": 200,
"data": {
"code": "acme-123456789"
}
}
```
#### Error Handling
If a quota is breached, the `code` field in the response data will be `nil`.
```
--------------------------------
### Parse Plugin Uninstallation Webhook Payload
Source: https://docs.usetrmnl.com/go/plugin-marketplace/plugin-uninstallation-flow
This example demonstrates how to parse the JSON payload received from the TRMNL uninstallation webhook. It assumes the payload contains a 'user_uuid'. This parsing is crucial for triggering backend 'teardown' processes associated with the uninstalled plugin.
```json
{
"user_uuid": "uuid-of-the-user"
}
```
--------------------------------
### Update Content with Stream Strategy (cURL)
Source: https://docs.usetrmnl.com/go/private-plugins/webhooks
Employ the 'stream' strategy for accumulating values in arrays, such as logging a series of temperature readings. The 'stream_limit' parameter prevents arrays from growing indefinitely by removing older values.
```cURL
curl "https://usetrmnl.com/api/custom_plugins/asdfqwerty1234" \
-H "Content-Type: application/json" \
-d '{"merge_variables": {"temperatures": [40, 42]}, "merge_strategy": "stream", "stream_limit": 10}' \
-X POST
```
--------------------------------
### Generate 1-bit PNG Image with ImageMagick
Source: https://docs.usetrmnl.com/go/diy/imagemagick-guide
Converts an input PNG image to a 1-bit grayscale PNG format using ImageMagick. This process can involve direct conversion or dithering with the Floyd-Steinberg algorithm to achieve specific visual effects. Dependencies: ImageMagick.
```bash
magick input.png -monochrome -colors 2 -depth 1 -strip png:output.png
```
```bash
magick input.png -dither FloydSteinberg -remap pattern:gray50 -depth 1 -strip png:output.png
```
```bash
% magick identify output.png
output.png PNG 800x480 800x480+0+0 8-bit Grayscale Gray 2c 1607B 0.000u 0:00.000
```
--------------------------------
### Back to TRMNL Button with Force Refresh
Source: https://docs.usetrmnl.com/go/plugin-marketplace/plugin-management-flow
You can provide a 'Back to TRMNL' button in your management UI. By appending `?force_refresh=true` to the return link, TRMNL will initiate a Screen Generation request upon the user's return and display a toast message confirming the action.
```APIDOC
## GET /manage?force_refresh=true
### Description
Provides a link to return to TRMNL, optionally triggering a screen generation request and displaying a toast message upon return.
### Method
GET
### Endpoint
`https://yourapp.com/manage?uuid={uuid}&force_refresh=true`
### Query Parameters
- **uuid** (string) - Required - A unique identifier for the user within the TRMNL plugin architecture.
- **force_refresh** (boolean) - Optional - If set to `true`, TRMNL will invoke a Screen Generation request and present a toast message upon the user's return.
### Request Example
`https://yourapp.com/manage?uuid=ae48d6ac-48f4-4aed-8464-bad68368e97c&force_refresh=true`
### Response
#### Success Response (302 Found)
Redirects to TRMNL. If `force_refresh=true` was provided, TRMNL will initiate a screen generation and show a toast message.
```
--------------------------------
### Generate BMP3 Image with ImageMagick
Source: https://docs.usetrmnl.com/go/diy/imagemagick-guide
Converts an input PNG image to BMP3 format, suitable for TRMNL devices. This command uses ImageMagick's 'magick' tool to apply monochrome and color depth settings. The output is a BMP3 file. Dependencies: ImageMagick.
```bash
magick input.png -monochrome -colors 2 -depth 1 -strip bmp3:output.bmp
```
```bash
% magick identify output.bmp
output.bmp BMP3 800x480 800x480+0+0 1-bit sRGB 2c 48062B 0.020u 0:00.001
```
--------------------------------
### TRMNL Metadata Object Example
Source: https://docs.usetrmnl.com/go/plugin-marketplace/plugin-screen-generation-flow
This JSON object represents the metadata payload sent by TRMNL to the plugin's markup URL. It contains user information, device details, system timestamp, and plugin-specific settings. This data can be used to personalize the content displayed.
```json
{
"user": {
"name": "Jim Bob",
"first_name": "Jim",
"last_name": "Bob",
"locale": "en",
"time_zone": "Eastern Time (US & Canada)",
"time_zone_iana": "America/New_York",
"utc_offset": -14400
},
"device": {
"friendly_id": "XXXXXX",
"percent_charged": 74.17,
"wifi_strength": 50,
"height": 480,
"width": 800
},
"system": {
"timestamp_utc": 1747596567
},
"plugin_settings": {
"instance_name": "Upcoming Assignments"
}
}
```
--------------------------------
### Logs API
Source: https://docs.usetrmnl.com/go/diy/byos
This endpoint retrieves logs from a device. It requires a device MAC address in the ID header.
```APIDOC
## GET /api/log
### Description
This endpoint retrieves logs from a device. It requires a device MAC address in the ID header.
### Method
GET
### Endpoint
/api/log
### Parameters
#### Headers
- **ID** (string) - Required - The MAC address of the device.
- **Content-Type** (string) - Required - application/json
### Request Example
```bash
curl "http://byos.local/api/log" \
-H 'ID: ' \
-H 'Content-Type: application/json'
```
### Response
#### Success Response (200)
- **logs** (array) - An array of log entries.
- Each element is an object with:
- **timestamp** (string) - The time the log was generated.
- **message** (string) - The log message.
#### Response Example
```json
{
"logs": [
{
"timestamp": "2023-10-27T10:00:00Z",
"message": "System started successfully."
},
{
"timestamp": "2023-10-27T10:05:15Z",
"message": "Network connection established."
}
]
}
```
```
--------------------------------
### Fetch and Advance Display Content (curl)
Source: https://docs.usetrmnl.com/go/private-api/screens
This curl command demonstrates how to fetch new screen content and automatically advance the playlist on a TRMNL device. It requires an access token for authentication. The response includes status, image URL, and refresh rate, among other fields.
```curl
curl https://usetrmnl.com/api/display --header "access-token:xxxxxx"
```
```json
{
"status":0,
"image_url":"https://trmnl.s3.us-east-2.amazonaws.com/path-to-img.png",
"image_name":"plugin-YYYY-MM-DD-TXX-XX-XXZ-hash",
"update_firmware":false,
"firmware_url":null,
"refresh_rate":"1800",
"reset_firmware":false
}
```