Public Beta — reserve early accessJoin Waitlist
ThumbAPI logoThumbAPI

Error Codes

Every error response from ThumbAPI follows this format:

{
  "error": "Human-readable error message"
}

HTTP Status Codes

400 — Bad Request

The request body is missing required fields or contains invalid values.

Error MessageCauseFix
title is requiredMissing or empty title fieldProvide a non-empty title string
format must be one of: youtube, instagram, x, blogpostInvalid format valueUse one of the four valid format strings
imageStyle must be one of: faceless, with-image, with-logoInvalid imageStyleUse one of the three valid style strings
personImage is required when imageStyle is with-image or with-logoMissing image for person/logo styleInclude base64-encoded image in personImage

401 — Unauthorized

Authentication failed.

Error MessageCauseFix
Missing authorization headerNo Authorization headerAdd Authorization: Bearer YOUR_KEY
Invalid API keyKey is wrong, expired, or revokedCheck your key in the dashboard

403 — Forbidden

Error MessageCauseFix
API access not enabledYour plan does not include API accessUpgrade your plan

429 — Too Many Requests

Error MessageCauseFix
Generation limit exceededYou've used all generations for this billing periodWait for reset or upgrade plan
Rate limit exceededToo many requests per secondAdd backoff/retry logic

500 — Internal Server Error

Error MessageCauseFix
Internal server errorSomething went wrong on our sideRetry after a few seconds. If persistent, contact support

Retry Strategy

For 429 and 500 errors, implement exponential backoff:

async function generateWithRetry(body, maxRetries = 3) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    const res = await fetch("https://api.thumbapi.dev/v1/generate", {
      method: "POST",
      headers: {
        "Authorization": `Bearer ${process.env.THUMBAPI_KEY}`,
        "Content-Type": "application/json",
      },
      body: JSON.stringify(body),
    });

    if (res.ok) return res.json();
    if (res.status === 429 || res.status >= 500) {
      await new Promise(r => setTimeout(r, 1000 * Math.pow(2, attempt)));
      continue;
    }

    // Client error — don't retry
    throw new Error(`API error ${res.status}: ${(await res.json()).error}`);
  }
  throw new Error("Max retries exceeded");
}

Next Steps