error.json
The shape never collapses to
{ body: {}, message: "" }. If the upstream platform returned nothing meaningful, we still attach a code, message, and requestId.
The thirteen codes
Reading errors in code
The pattern is the same regardless of language:handle.ts
Why this matters
Every code on this page is narrow, stable, and documented. If we discover a new failure shape, we add a new code with its own page rather than fold it into an existing one — broad error codes that mask multiple underlying causes are the failure mode this design exists to defeat.Best practices
1
Branch on `code`, never on `message`
Error messages are tuned for humans and can change between releases. The
code field is part of the API contract — it’s stable. Always switch on code (and rule for preflight failures), never on substring match against message.2
Respect `Retry-After` and the `X-RateLimit-Limit` ceiling
On
rate_limited responses, the Retry-After header tells you how many seconds to wait. The X-RateLimit-Limit header is on every response (not just 429s) and carries the static per-route ceiling — useful to size your client-side concurrency without first probing a 429. We deliberately do not publish RateLimit-Remaining or RateLimit-Reset in v1: until per-key counting lands, those values would be misleading across tenants. Honor Retry-After on 429 and you’ll never need them.3
Treat platform 4xx as caller-fixable, 5xx as platform-fault
Platform
4xx responses (mapped to letmepost platform_rejected with the upstream platformResponse) usually mean the post itself violated platform rules — character count, missing media, banned URL pattern. These can be fixed by editing the post.Platform 5xx responses (mapped to platform_unavailable) are upstream issues. Retry with backoff; check the status page if it persists.4
Follow `docUrl` for unknown codes
Every error response includes a
docUrl that points at the corresponding code’s docs page, and a ruleUrl when rule is present. If you hit an error code you don’t recognize, the docUrl value will take you to its remediation page directly.5
Always grep by `requestId`
Every response carries a
requestId in the body and the x-request-id response header. When you open a support issue or check the logs, include it — it indexes the full request log for that operation across the entire pipeline.See also
- Each code links to its own page above with reproduction, response shape, and remediation.
preflightfor the full rule catalog whencodeispreflight_failed.

