GenzoAI/platform

Errors

Errors return a non-2xx status and a JSON body with a stable machine-readable type. Branch on type, not on the human-readable message — messages change, types do not.

error shape
{
  "error": {
    "type": "invalid_request",
    "message": "The prompt field is required.",
    "details": { "prompt": ["The prompt field is required."] }
  },
  "request_id": "req_01JCX8..."
}

Always log request_id. It is the fastest way for us to trace a failing call.

Status codes

CodetypeMeaningRetry?
400invalid_requestMalformed body or failed validationNo — fix the request
401unauthenticatedMissing, malformed or revoked keyNo
403forbiddenKey lacks the required ability, or plan excludes this modelNo
402insufficient_creditsBalance or key cap would be exceededAfter topping up
404not_foundUnknown generation, model or providerNo
422unprocessableValid shape, impossible values (e.g. unsupported size)No
429rate_limitedKey or account rate limit exceededYes — honour Retry-After
500server_errorFault on our sideYes, with backoff
502provider_errorUpstream provider failed or timed outYes, with backoff
503provider_unavailableProvider disabled or over capacityYes, or switch provider

Retry policy

Retry only 429, 500, 502 and 503. Retrying a 4xx other than 429 will fail identically every time.

python — exponential backoff with jitter
import time, random, requests

RETRYABLE = {429, 500, 502, 503}

def call(url, headers, payload, attempts=4):
    for i in range(attempts):
        r = requests.post(url, headers=headers, json=payload, timeout=120)
        if r.status_code < 400:
            return r.json()
        if r.status_code not in RETRYABLE or i == attempts - 1:
            r.raise_for_status()
        wait = float(r.headers.get("Retry-After", 2 ** i)) + random.random()
        time.sleep(wait)

Failed generations

A 200 response can still carry status: "failed" — the request was accepted and billed nothing, but the provider could not complete it. This is distinct from a transport error. Check status on every generation, not just the HTTP code.

200 OK, failed generation
{
  "id": "550e8400-...",
  "status": "failed",
  "error": "Provider rejected the prompt: content policy.",
  "credits_used": 0
}

Provider content policies

Upstream providers apply their own safety filters. A prompt they decline surfaces as a failed generation with the provider's reason, not as a GenzoAI error. If your workload is being refused, trying a different provider is often the fastest fix — policies differ between vendors.