Skip to content

Errors

All errors use a consistent JSON envelope and standard HTTP status codes.

Error envelope

json
{
  "error": "error_code",
  "message": "Human-readable explanation."
}
  • error — a stable, machine-readable code. Branch on this, not on the message text.
  • message — a human-readable description, safe to log. It may change; don't parse it.

Status codes

StatusMeaning
200Success
400Bad request — a parameter failed validation
401Unauthorized — missing or invalid API key
404Not found — no matching product in your partner catalog
429Too many requests — rate limit exceeded
500Internal error — an unexpected server-side problem

Error codes

errorStatusMeaningHow to fix
missing_api_key401No key in Authorization or X-API-Key.Send your key in a header.
invalid_api_key401The key is unknown or has been revoked.Check the key; issue a new one if revoked.
invalid_sku400SKU is empty, over 50 chars, or has disallowed characters.Match ^[A-Za-z0-9._-]+$, 1–50 chars.
invalid_product_id400Product ID is not a positive integer.Pass a positive integer id.
sku_not_found404No product with that SKU in your partner catalog.Verify the SKU; confirm the product is in your catalog.
product_not_found404No product with that ID in your partner catalog.Verify the ID; confirm the product is in your catalog.
rate_limit_exceeded429More than 100 requests in a minute.Wait for the Retry-After seconds, then retry.
internal_error500An unexpected server-side error.Retry with backoff; contact support if it persists.

Handling errors

Check res.ok (or the status code) before reading the body, and branch on the error code:

js
const res = await fetch(url, {
  headers: { Authorization: `Bearer ${process.env.TDC_API_KEY}` },
});

if (!res.ok) {
  const { error, message } = await res.json();

  switch (error) {
    case 'rate_limit_exceeded': {
      const retryAfter = Number(res.headers.get('Retry-After')) || 60;
      // wait `retryAfter` seconds, then retry
      break;
    }
    case 'sku_not_found':
    case 'product_not_found':
      // treat as "no TDC content for this product"
      break;
    case 'missing_api_key':
    case 'invalid_api_key':
      // configuration problem — alert, don't retry
      break;
    default:
      throw new Error(`TDC API ${res.status}: ${error} — ${message}`);
  }
}

Retry guidance

  • Retry 429 (after Retry-After) and 500 (with exponential backoff).
  • Don't retry 400, 401, or 404 — the request needs to change first.

The Desire Company — Enterprise API