Skip to main content
Every failure response from the API uses the same envelope:
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.
  • preflight for the full rule catalog when code is preflight_failed.