Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.letmepost.dev/llms.txt

Use this file to discover all available pages before exploring further.

Every failure response from the API uses the same envelope:
error.json
{
  "error": {
    "code": "preflight_failed",
    "message": "Post text is 312 graphemes; Bluesky allows at most 300.",
    "rule": "bluesky.text.max_graphemes",
    "platform": "bluesky",
    "platformVersion": "atproto-2026-04",
    "platformResponse": null,
    "remediation": "Shorten the post to 300 graphemes or fewer.",
    "requestId": "req_01HY6X4AWBJM2K9F2PTQMRD9JQ"
  }
}
fieldalways setmeaning
codeyesone of the eleven values below
messageyeshuman-readable explanation
rulewhen knownpreflight rule id or validation field path
platformwhen knownwhich upstream platform was involved
platformVersionwhen knownthe pinned upstream API version we targeted
platformResponsewhen knownraw upstream body, untouched
remediationusuallyactionable next step
requestIdalwaysechoed in the x-request-id response header
traceIdwhen onOTel trace id when tracing is active
The shape never collapses to { body: {}, message: "" }. If the upstream platform returned nothing meaningful, we still attach a code, message, and requestId.

The eleven codes

codetypical HTTPwhat it means
validation_failed400Request body or query failed schema validation.
preflight_failed400A documented platform constraint failed before the upstream call.
platform_auth_failed401, 403The connected account’s token is missing, expired, or revoked.
platform_rejected4xx (502 if mapped from an upstream 5xx)Upstream rejected the call after preflight passed.
platform_unavailable502, 503Upstream is down or rate-limited; safe to retry later.
internal_error500Unexpected server-side issue. Includes a requestId to file.
unauthenticated401Bearer header missing, malformed, or key revoked.
unauthorized403Authenticated, but not allowed to perform this action.
not_found404Resource doesn’t exist or is out of scope.
idempotency_conflict409Same Idempotency-Key reused with a different body.
rate_limited429Per-key rate limit exhausted. Honor Retry-After.

Reading errors in code

The pattern is the same regardless of language:
handle.ts
const res = await fetch(url, init);
if (!res.ok) {
  const body = await res.json();
  // body.error is the envelope above.
  if (body.error.code === "preflight_failed") {
    // body.error.rule is the canonical rule id.
    // Look it up at /docs/preflight/<rule>/ for context.
    throw new PreflightError(body.error.rule, body.error.message);
  }
  if (body.error.code === "rate_limited") {
    const retry = Number(res.headers.get("retry-after") ?? 5);
    await sleep(retry * 1000);
    return retryOnce();
  }
  throw new Error(\`\${body.error.code}: \${body.error.message}\`);
}

Why this matters

Ayrshare’s own documentation admits their error 138 “masks multiple distinct underlying causes.” That’s the failure mode we built to defeat. 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.

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.