Delivery, retries & errors
The Web API stores pending attempts with a 10-minute delivery window. A successful HTTP exchange can still mean that delivery is pending, and a handled request does not necessarily mean visible output or accepted routine input.
What delivered means
Section titled “What delivered means”200 delivered means the firmware or app bridge reported the request consumed and handled. It is a terminal success for the delivery path.
It does not guarantee visible rendering or routine acceptance. The board validates input against the current routine step and can reject it while still acknowledging delivery. That rejection is reported on the board, not as an API error. See routine input.
202 accepted means handling has not yet been confirmed. It is the normal initial response, including when the board is offline. It is a non-terminal state, not proof of success or failure.
Check a request
Section titled “Check a request”There is no public status endpoint. You cannot query requestId directly. GET /api/display is reserved for firmware polling with a separate board credential, not for checking a request with X-Motherboard-Api-Id.
- Include a unique
Idempotency-Keyon the initialPOST /api/display. - Retain that key, the board’s API ID, and the exact request body.
- Re-send the identical
POSTwith the same API ID, key, and body.
The response reports the stored attempt’s current state without creating a second display attempt:
| Result | Meaning |
|---|---|
200 delivered |
Handling was confirmed. |
202 accepted |
No terminal result has been recorded. |
502 upstream_failed |
Handling failed. |
504 timeout |
The stored attempt expired. |
The curl and JavaScript examples keep the key and body unchanged for this purpose.
Reuse keys only for the same request
Section titled “Reuse keys only for the same request”An idempotency key is scoped to one motherboard. Use a new UUID for each logical display request.
Bound your retries
Section titled “Bound your retries”Use bounded backoff and a client-side deadline. Do not poll in a tight loop: rechecking a pending request may wake the delivery bridge.
If the API still returns 202 when your deadline is reached, treat the result as unknown, not failed. A pending request is not guaranteed to become 504 automatically just because time has elapsed.
The 10-minute delivery window is not an automatic HTTP status transition: firmware polling excludes attempts past their expiry time, but rechecking a stored attempt still marked pending returns 202. An attempt recorded as expired, including one superseded by a newer pending request, returns 504 timeout.
Rechecking an existing attempt and intentionally starting another attempt are different operations. Follow the status-specific guidance below before creating a new key.
Rate limits
Section titled “Rate limits”The API counts stored attempts created during the preceding 60 seconds. Requests are rejected with 429 rate_limited once either limit is reached:
- 30 attempts for one motherboard, even if its API ID changes.
- 60 attempts from one source IP across boards.
Rechecks do not create another attempt, but the limit check runs before idempotency lookup, so they can also receive 429. Back off before trying again; the handler does not provide a Retry-After header.
HTTP status and error reference
Section titled “HTTP status and error reference”The value column refers to status on successful responses and code on normal errors. The 405 response uses error instead.
| HTTP | Value | State | Meaning and next step |
|---|---|---|---|
200 OK |
delivered |
Terminal success | The firmware or app bridge reported the request handled. |
202 Accepted |
accepted |
Non-terminal | Stored but not confirmed, including while offline. Recheck using the same key and body. |
400 Bad Request |
invalid_request |
Rejected | Correct the JSON body, kind, text, orientation, or zone, or reduce oversized text. |
404 Not Found |
not_found |
Rejected | The API ID is missing, unknown, or no longer valid. Check it with the board owner. |
405 Method Not Allowed |
METHOD_NOT_ALLOWED |
Rejected | Use POST for public requests. Response: {"error":"METHOD_NOT_ALLOWED"} with Allow: GET, POST; GET is for firmware polling. |
429 Too Many Requests |
rate_limited |
Rejected | Retry later with backoff. |
500 Internal Server Error |
server_error |
Unknown | Retry the identical request with the same idempotency key. |
502 Bad Gateway |
upstream_failed |
Terminal failure | The board could not process the request. Use a new key only if you intentionally retry it. |
504 Gateway Timeout |
timeout |
Terminal failure | The stored attempt is marked expired or superseded. Use a new key only if you intentionally retry it. |
See the response examples for the JSON envelopes.
Pending attempts and reconnects
Section titled “Pending attempts and reconnects”- The board polls for pending input; the API also sends a silent wake and broadcasts to an active app bridge when available.
- Wake and app bridge broadcast failures leave the stored request pending. A delayed wake, firmware poll, or bridge reconnect can still consume an eligible attempt.
- When polling or bridge recovery finds multiple unexpired pending attempts for one board, it selects the newest and marks older ones as superseded. Do not use this API as a queue for routine inputs; confirm each step before submitting the next value.
- Once an attempt is consumed, it is not replayed.
- The board owner can rotate its API ID at any time; old IDs stop working immediately.