Error Handling

Handle errors gracefully with standard error codes.

Error Response Format

All API errors follow a consistent JSON format with an error code and a human-readable message.

{
  "error": {
    "code": "error_code_here",
    "message": "A human-readable description of the error."
  }
}

Error Codes

StatusCodeDescription
401missing_api_keyNo X-API-Key header was provided in the request.
401invalid_api_keyThe provided API key is invalid, expired, or has been revoked.
402quota_exceededYour monthly request quota has been exceeded. Upgrade your plan.
422invalid_imageThe image field is missing, not valid base64, or exceeds 5MB.
422invalid_requestThe request body is not valid JSON.
502inference_errorThe ML inference service is temporarily unavailable. Retry with backoff.

Example Error Responses

Missing API Key (401)

{
  "error": {
    "code": "missing_api_key",
    "message": "No API key provided. Include your key in the X-API-Key header."
  }
}

Invalid Image (422)

{
  "error": {
    "code": "invalid_image",
    "message": "Image exceeds the maximum size of 5 MB."
  }
}

Inference Error (502)

{
  "error": {
    "code": "inference_error",
    "message": "ML inference service is temporarily unavailable. Please retry."
  }
}

Best Practices

  • Always check the HTTP status code before parsing the response body.
  • Implement exponential backoff for 502 errors (inference service may be cold-starting).
  • Monitor your quota usage via response headers to avoid unexpected 402 errors.
  • Do not retry 401 or 422 errors — they indicate a client-side issue that needs fixing.
  • Use the error.code field for programmatic error handling, not the message.

Retry Example

Here's a JavaScript example with exponential backoff for transient errors:

async function analyzePalm(imageBase64, apiKey, retries = 3) {
  for (let attempt = 0; attempt < retries; attempt++) {
    const res = await fetch(
      "https://api.trace-line.site/v1/palm/analyze",
      {
        method: "POST",
        headers: {
          "X-API-Key": apiKey,
          "Content-Type": "application/json",
        },
        body: JSON.stringify({ image: imageBase64 }),
      }
    );

    if (res.ok) return res.json();

    const error = await res.json();

    // Only retry on transient errors
    if (res.status !== 502) throw error;

    // Exponential backoff: 1s, 2s, 4s
    await new Promise((r) =>
      setTimeout(r, 1000 * Math.pow(2, attempt))
    );
  }

  throw new Error("Max retries exceeded");
}