You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Terminus 0.52.0 removed base64 payload support, so the add-on
needs a way to hand Terminus a URL it can fetch. URI mode sends
the add-on's screenshot endpoint URL and lets Terminus pull the
image itself.
Legacy base64 mode is preserved as an opt-in for Terminus ≤ 0.51.0
users. A delivery-mode selector in the BYOS schedule config
defaults to `data` so existing schedules keep working unchanged
until users opt in to URI mode.
Includes supporting pieces for the feature:
- `addon_base_url` + `ByosDeliveryMode` added to the BYOS config
- `BYOS_DEFAULT_DELIVERY_MODE` constant shared by UI and extractor
- Screenshot URL builder threads `url` query param in generic mode
so Terminus fetches hit the screenshot handler, not the UI HTML
- Device preset selection auto-fills crop dimensions from viewport
- Webhook format tests restructured by mode (URI / data / explicit)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
For BYOS Hanami, the add-on offers two **delivery modes**:
366
+
367
+
-**URI mode** (recommended, required for Terminus ≥ 0.52.0): the add-on sends a URL; Terminus fetches the image itself. Set **Add-on URL** to an address **Terminus** can reach — often *not*`localhost`. See the guide for deployment topologies.
368
+
-**Legacy base64 mode**: inlines the image in the JSON body. Only works on Terminus ≤ 0.51.0.
364
369
365
370
See **[Webhook Formats Guide](docs/webhook-formats.md)** for:
366
-
- Detailed format specifications
371
+
- Detailed format specifications and delivery mode selection
367
372
- JWT authentication setup for BYOS
373
+
- Deployment topology examples for the Add-on URL (Docker, LAN, reverse proxy)
For self-hosted [BYOS (Build Your Own Server)](https://github.com/usetrmnl/byos) installations, this format wraps the image in a JSON payload with metadata.
33
+
For self-hosted [Terminus / BYOS Hanami](https://github.com/usetrmnl/terminus) installations, this format wraps the screen metadata in a JSON payload and delivers the image to `POST /api/screens`.
34
+
35
+
### Delivery Modes
36
+
37
+
Terminus supports two incompatible payload shapes depending on its version. The add-on exposes both via a **Delivery Mode** dropdown in the schedule UI.
38
+
39
+
| Mode | Terminus versions | Image transport |
40
+
|------|-------------------|-----------------|
41
+
|**URI** (recommended) |`≥ 0.11.0`, required from `0.52.0` onward | Terminus fetches the image from the add-on over HTTP |
42
+
|**Legacy base64**|`≤ 0.51.0` only | Add-on inlines the image as base64 in the JSON body |
43
+
44
+
Base64 support was removed from Terminus in `0.52.0` (released 2026-04-01). New installations should pick **URI** mode; older deployments can stay on **Legacy base64** until they upgrade.
45
+
46
+
### URI Mode
47
+
48
+
In URI mode, the add-on sends a small JSON payload referencing a screenshot endpoint on the add-on itself. Terminus then calls back to that URL, downloads the dithered image, and stores it.
-`preprocessed: true` tells Terminus to use the image as-is without running its own dithering. The add-on always sends preprocessed images since it dithers locally.
70
+
- The add-on's screenshot endpoint must be reachable without authentication, or the Add-on URL must include any credentials Terminus needs.
71
+
- If URI mode is selected but **Add-on URL** is blank, the add-on throws a clear error at delivery time rather than silently falling back.
72
+
73
+
#### Setting the Add-on URL
74
+
75
+
> ⚠️ **This is the URL Terminus will use to reach the add-on — not the URL you use in your browser.**
76
+
>
77
+
> The Add-on URL field must resolve from *Terminus's* network vantage point, not yours. If Terminus runs in Docker on the same host, `http://localhost:10000` will **not** work — inside the Terminus container, `localhost` points at the container itself, and nothing is listening on port `10000` there.
78
+
79
+
Think of it as two asymmetric network hops:
80
+
81
+
```
82
+
You (browser) ──────▶ Add-on UI (your browser resolves "localhost")
83
+
Add-on ──────▶ Terminus (webhook URL, see "Webhook URL" field)
84
+
Terminus ──────▶ Add-on screenshot (Add-on URL, see this section)
85
+
```
86
+
87
+
The second and third hops resolve DNS from different vantage points, so the Webhook URL and the Add-on URL often need to be different strings even when both services are on the same physical machine.
88
+
89
+
Pick the value that matches your deployment topology:
90
+
91
+
| Where Terminus runs | Set Add-on URL to | Notes |
92
+
|---|---|---|
93
+
| Docker on the same host as the add-on (Docker Desktop on Mac/Windows) |`http://host.docker.internal:10000`| Docker Desktop's built-in DNS name for the host machine |
94
+
| Docker on the same Linux host |`http://172.17.0.1:10000` or your LAN IP |`172.17.0.1` is the default docker bridge gateway; LAN IP also works |
95
+
| A different machine on the same LAN |`http://<add-on-lan-ip>:10000`| Use the add-on host's routable IP, never `localhost`|
96
+
| Behind a reverse proxy / public URL |`https://trmnl.example.com`| Whatever public hostname forwards to the add-on's port 10000 |
97
+
| As a Home Assistant add-on, accessed via ingress | The add-on's ingress URL | See your HA installation's external ingress configuration |
98
+
99
+
**Verification shortcut.** Before retrying a failed schedule, shell into the Terminus container and confirm it can reach the add-on:
100
+
101
+
```sh
102
+
docker compose -p terminus-development exec web \
103
+
curl -sI http://host.docker.internal:10000/health
104
+
# Expected: HTTP/1.1 200 OK
105
+
```
106
+
107
+
If that curl fails, fix the URL before touching anything else — every downstream error (`ECONNREFUSED`, `improper image header` from MiniMagick, 500 from Terminus) traces back to this one setting.
108
+
109
+
### Legacy Base64 Mode
110
+
111
+
Legacy mode embeds the image directly in the JSON body. Keep it selected only if your Terminus is `≤ 0.51.0`.
0 commit comments