memeworld
Documentation

REST

Errors

Every error code the API returns, and what to do about it.

Every REST error is the same shape, including 404s:

{ "code": "BAD_REQUEST", "message": "captions: Too many captions" }

code is stable and worth branching on. message is written for a human — or an agent — to act on, and may change.

Over MCP the same failures come back as isError with the message as text, so a model reads the explanation rather than a transport-level exception.

Codes

  • BAD_REQUEST (400) — the body failed validation. The message names each field that was wrong.
  • UNAUTHORIZED (401) — no key or token on an endpoint that needs one. See Auth.
  • RATE_LIMITED (429) — over a policy; Retry-After says for how long.
  • NOT_FOUND (404) — no template with that id or slug, or no such route.
  • TOO_MANY_CAPTIONS (400) — more captions than the template has text boxes.
  • UNKNOWN_TEXT_BOX (400) — a caption keyed by an id the template doesn't have. The message lists the ids it does have.
  • FORMAT_MISMATCH (400) — format: "gif" against a still template.
  • UNKNOWN_PRESET (400) — no GIF preset by that name.
  • GIF_TOO_LARGE (413) — the source GIF is beyond what the renderer will encode.
  • UNSUPPORTED_TEMPLATE (415) — the template file can't be decoded for this render.
  • TEMPLATE_MISSING (404) — the template exists in the catalog but its file is unavailable.
  • INSUFFICIENT_CREDITS (402) — the account can't pay for a face swap. The body carries balance and required. See Credits.
  • BAD_FACE_IMAGE (400) — the face photo isn't valid base64.
  • UNSUPPORTED_FACE_IMAGE (415) — it decoded, but isn't a JPEG, PNG or WebP.
  • FACE_IMAGE_TOO_LARGE (413) — over the 10 MB limit.
  • AI_UNAVAILABLE (503) — the model behind suggestions is down. Retry, or fall back to search_templates.
  • NO_SUGGESTIONS (400) — nothing came back for that prompt. Reword it.
  • INTERNAL_ERROR (500) — a bug on our side.

Not an error

overBudget: true on a GIF render is a warning, not a failure. The file is valid and the URL works; it is simply larger than the chosen preset targets, and somewhere with an enforced ceiling — a Discord emoji slot, say — will reject it. Re-render with a stricter preset.