error.code is a stable machine-readable string. The error.message is human-readable and may change between versions. Parse code, log message.
Error codes
| Code | HTTP | When it fires | Recommended client action |
|---|---|---|---|
unauthorized | 401 | Missing, malformed, or invalid Authorization header | Check the header is Bearer lymo_...; re-issue the key if it’s been revoked |
invalid_key_metadata | 401 | Key signature is valid but Lymo-specific metadata is missing | Re-issue the key from the web app — it was created outside the normal flow |
forbidden | 403 | Key lacks the required scope, or the organization is inactive | Check your key’s scopes; contact support if the org should be active |
not_found | 404 | Resource doesn’t exist, or it exists in a different organization | See cross-tenant 404 below |
bad_request | 400 | Malformed header — e.g. Idempotency-Key longer than 256 characters | Fix the header and retry |
validation_failed | 422 | Query parameters or request body failed schema validation | Read message for the failing field path; fix and retry |
invalid_webhook_url | 422 | POST /v1/webhooks destination URL isn’t on your org’s hostname allowlist | See Webhooks → Hostname allowlist |
rate_limited | 429 | Too many requests for this key (when enforcement is configured — see below) | Honor the Retry-After header (seconds); back off exponentially thereafter |
service_unavailable | 503 | Key-verification service is temporarily unavailable | Retry with backoff; escalate if it persists more than a minute |
internal_error | 500 | Unexpected server error | Retry once; if it persists, report the request_id |
Cross-tenant 404
Resources that belong to a different organization return404 not_found, not 403 forbidden. This is intentional — 403 would leak the fact that an ID exists; 404 is indistinguishable from “never existed.” This applies to every resource path, not just videos.
Concretely: if your key is for org A, calling GET /v1/videos/{id} with a video ID from org B returns:
404, the most common cause is that the API key is scoped to a different organization than you expected. Check it with:
Key self-revocation
If a key is compromised, the holder can revoke it without web UI access:401 unauthorized.
Using request_id
Every response — success or error — includes meta.request_id. When reporting issues, include it: we can trace the exact request server-side, including timing, inputs, and which backend service handled it.
req_ followed by 32 lowercase hex characters (a UUID with dashes removed). The same ID is echoed on the X-Request-Id response header so you can grep logs end-to-end.
Rate limits
Rate-limit enforcement is per-API-key. When a limit is exceeded the response is429 rate_limited with a Retry-After header specifying seconds to wait:
Rate limits are not yet enforced on all issued keys. Future versions will apply sensible defaults per scope. Design clients to always honor
Retry-After rather than hard-coding intervals, so the switch to enforcement is a no-op for you.Validation errors
validation_failed (422) is the most common error during development. The message field names the offending field path:
limitoutside1–100(default is 25)created_after/created_beforenot a valid ISO 8601 timestampstatusfilter not in the allowed enum — see the API Reference tab for per-resource status values- Missing required body field on
POST /v1/webhooks