Errors & retries

v2 status codes

Status Meaning Retry?
200 Request processed. Check detection.
400 Image couldn't be used (invalid_image). No. Fix the image.
401 Missing or invalid API key (unauthorized). No. Fix the key.
404 Unknown model (model_not_found) or path (not_found). No.
405 Wrong HTTP method (method_not_allowed). No.
422 Request body failed validation (invalid_request). No. Fix the request.
500 Unexpected server error (internal_error). Yes, with backoff (a small number of times).
429 / 502 / 503 / 504 Returned by the hosting platform during overload, deploys, or timeouts. The body may not be JSON. Yes, with exponential backoff.
  • Retry only 429, 500, 502, 503, and 504, and network errors or timeouts.
  • Use exponential backoff with jitter (for example 1 s, 2 s, 4 s), at most 3 attempts.
  • Predictions don't change server state, so retrying is safe.
  • Parse error bodies defensively: if the body isn't JSON, fall back to the HTTP status.
import random
import time
import requests

RETRYABLE = {429, 500, 502, 503, 504}

def predict(image_b64, api_key, base_url, request_id=None, attempts=3):
    headers = {"api-key": api_key}
    if request_id:
        headers["X-Request-ID"] = request_id
    for attempt in range(attempts):
        try:
            r = requests.post(f"{base_url}/v2/predict", headers=headers,
                              json={"image": image_b64}, timeout=60)
        except requests.RequestException:
            if attempt == attempts - 1:
                raise
        else:
            if r.status_code not in RETRYABLE or attempt == attempts - 1:
                return r
        time.sleep((2 ** attempt) + random.random())

For v1 error behaviour, see API v1 errors.