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.

