Plugin Screen Generation Flow
Creating image content to display on a user's device.

TRMNL generates a screen every X minutes, where X is the refresh frequency set by the user -- never faster than the Supported Refresh Interval you chose during Plugin Creation. A user can also force a refresh by hand.
TRMNL generates screens by sending a POST request to the plugin_markup_url endpoint you specified during Plugin Creation. The request body will include the user_uuid (that particular user's plugin connection UUID) and some metadata. The request header contains an authorization key with the user's plugin connection access_token as the Bearer token. Here's an example of our server request:
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[user][first_name]=Jim&trmnl[device][width]=800&trmnl[plugin_settings][instance_name]=Upcoming+Assignments'The body is form-encoded, not JSON. The trmnl metadata arrives as nested bracket params (trmnl[device][width]=800), which Rails, PHP + Express (with extended: true) parse into a nested object for you.
The trmnl object in this payload may or may not be useful for your plugin, but includes the user-defined instance name, device dimensions, user timezone, and so on. device describes the first device with this instance in its playlist (or the user's first device if none). Here's an example, subject to change:
We wait up to 10 seconds for your server. On a timeout or an empty body we pause briefly and try once more, then give up on that refresh. We follow up to 5 redirects, but drop the Authorization header on any redirect to a different host. Your markup URL must resolve to a public IP address -- localhost + private network addresses are refused, so use a tunnel while developing.
Your web server should respond with a JSON object whose keys are named markup, markup_quadrant, and so on to satisfy each layout offered by TRMNL. This markup should include whatever values you want the user to see rendered on their screen.
Pro tip: use the Private Plugin markup editor to develop the frontend of your plugin. This in-browser text editor supports live refresh and automatically applies the correct styling and JavaScript helpers to your markup.
TRMNL uses the markup in your server's response to generate an e-ink friendly image. If the user connecting your plugin created a "full screen" playlist item, TRMNL will leverage the HTML inside the markup node. If they connected your plugin as part of a left/right Mashup, TRMNL will look for HTML inside the markup_half_vertical node.
TRMNL wraps each layout in its own <div class="view view--full"> (or view--half_horizontal, etc), so start your markup at the layout element. A layout you leave out renders as "view not available."
Here's an example of a valid server response:
Every markup value is rendered as a Liquid template. Add an optional merge_variables object to your response and reference its keys in any layout, so you only build the data once:
Only merge_variables is available to Liquid here -- the trmnl metadata we send you isn't. Since markup is always parsed as Liquid, escape any literal Liquid delimiters (double curly braces) in your HTML.
Note: in order for your plugin to be published in the TRMNL public marketplace, you must provide HTML for all available markup layouts. View them here.
Last updated