Developers/Error Handling

Error Handling

Handle API errors gracefully with structured error codes and retry strategies.

Error response format

All errors return JSON with a consistent structure. The error field is safe to display to users. The code field is stable and safe to match against in code.

json
{
  "error": "Human-readable error message",
  "code": "MACHINE_READABLE_CODE"
}

HTTP status codes

The API uses standard HTTP status codes to indicate the result of a request.

200 OKSuccess
401 UnauthorizedMissing or invalid API key
403 ForbiddenValid key but insufficient scopes
404 Not FoundResource doesn't exist
429 Too Many RequestsRate limit exceeded
500 Internal Server ErrorSomething went wrong on our side

Error codes

Each error response includes a machine-readable code field. Use these codes to handle specific error conditions in your integration.

CodeDescriptionStatus
AUTH_REQUIREDNo API key provided401
INVALID_KEYKey doesn't exist or has been revoked401
INSUFFICIENT_SCOPEKey lacks required scope403
NOT_FOUNDResource not found404
RATE_LIMITEDDaily rate limit exceeded429
INTERNAL_ERRORUnexpected server error500

Handling errors in code

Use the code field to programmatically handle different error types. Here is an example in JavaScript:

javascript
async function fetchPrograms(apiKey) {
  const res = await fetch(
    "https://api.theaffiliateindex.com/v1/programs",
    { headers: { "X-API-Key": apiKey } }
  );

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

    switch (error.code) {
      case "AUTH_REQUIRED":
      case "INVALID_KEY":
        throw new Error("Check your API key");
      case "INSUFFICIENT_SCOPE":
        throw new Error("API key needs more permissions");
      case "RATE_LIMITED":
        // Wait until reset time
        const resetAt = error.resetAt;
        throw new Error(`Rate limited until ${resetAt}`);
      case "NOT_FOUND":
        return null;
      default:
        throw new Error(error.error);
    }
  }

  return res.json();
}

Retry strategies

*

When to retry

  • Don't retry 401 / 403 errors — they won't resolve without action.
  • For 429 errors, wait until the resetAt timestamp or sleep for the remaining time.
  • For 500 errors, retry with exponential backoff (max 3 retries).

A simple retry helper with exponential backoff:

javascript
async function fetchWithRetry(url, headers, retries = 3) {
  for (let i = 0; i < retries; i++) {
    const res = await fetch(url, { headers });
    if (res.ok) return res.json();
    if (res.status === 429 || res.status >= 500) {
      await new Promise(r => setTimeout(r, 1000 * Math.pow(2, i)));
      continue;
    }
    const error = await res.json();
    throw new Error(error.error);
  }
  throw new Error("Max retries exceeded");
}