Appearance
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
| Status | Meaning |
|---|---|
200 | Success |
400 | Bad request — a parameter failed validation |
401 | Unauthorized — missing or invalid API key |
404 | Not found — no matching product in your partner catalog |
429 | Too many requests — rate limit exceeded |
500 | Internal error — an unexpected server-side problem |
Error codes
error | Status | Meaning | How to fix |
|---|---|---|---|
missing_api_key | 401 | No key in Authorization or X-API-Key. | Send your key in a header. |
invalid_api_key | 401 | The key is unknown or has been revoked. | Check the key; issue a new one if revoked. |
invalid_sku | 400 | SKU is empty, over 50 chars, or has disallowed characters. | Match ^[A-Za-z0-9._-]+$, 1–50 chars. |
invalid_product_id | 400 | Product ID is not a positive integer. | Pass a positive integer id. |
sku_not_found | 404 | No product with that SKU in your partner catalog. | Verify the SKU; confirm the product is in your catalog. |
product_not_found | 404 | No product with that ID in your partner catalog. | Verify the ID; confirm the product is in your catalog. |
rate_limit_exceeded | 429 | More than 100 requests in a minute. | Wait for the Retry-After seconds, then retry. |
internal_error | 500 | An 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(afterRetry-After) and500(with exponential backoff). - Don't retry
400,401, or404— the request needs to change first.

