Skip to content

Errors & Rate Limits

The Blaick API uses conventional HTTP status codes and returns a structured JSON body for errors.

Error format

Errors carry a detail object. Simple errors use a string; richer errors use an object with a machine-readable code:

{
  "detail": {
    "code": "INSUFFICIENT_TOKENS",
    "message": "You don't have enough tokens for this request.",
    "required_tokens": 500,
    "current_balance": 100
  }
}

Always branch on the HTTP status code first, then read detail.code (when present) for specifics.

Status codes

Status Meaning What to do
200 Success
400 Bad request — malformed JSON or invalid parameters Fix the request body.
401 Unauthorized — missing, invalid, or revoked token Check the Authorization header and key validity.
402 Payment required — subscription past due or out of tokens Top up tokens or resolve billing. See Usage & Tokens.
403 Forbidden — model not available on your plan, or missing role Choose an eligible model, or upgrade.
404 Not found — unknown conversation, model, or resource Verify the ID.
429 Rate limited — too many requests Back off and retry (see below).
503 Model temporarily unavailable Retry with backoff, or try another model.

Common error codes

detail.code Status Meaning
INSUFFICIENT_TOKENS 402 Not enough token balance to cover the request.
SUBSCRIPTION_REQUIRED 403 The model requires an active subscription (not available on trial).
PAYMENT_REQUIRED 402 Subscription payment failed or is past due.
MODEL_UNAVAILABLE 503 The upstream provider is temporarily unreachable.
RATE_LIMITED 429 You've exceeded your request rate.

Estimate before you spend

A 402 INSUFFICIENT_TOKENS response includes required_tokens and current_balance, so you can tell the user exactly how much they're short.

Rate limits

Rate limits depend on your account tier:

Tier Requests / minute Requests / day
Trial 10 100
Standard 60 5,000

When you exceed a limit you get a 429. Handle it with exponential backoff and jitter:

import time, random, requests

def post_with_retry(url, headers, json, max_retries=5):
    for attempt in range(max_retries):
        resp = requests.post(url, headers=headers, json=json)
        if resp.status_code != 429:
            return resp
        # Exponential backoff with jitter: ~1s, 2s, 4s, 8s ...
        sleep = (2 ** attempt) + random.random()
        time.sleep(sleep)
    return resp  # give up; caller inspects the final 429

Guidelines:

  • Retry 429, 503, and network errors with backoff. Don't retry 400, 401, 402, or 403 — those won't fix themselves.
  • Add jitter so many clients don't retry in lockstep.
  • Cap retries (e.g. 5 attempts) and surface a clear message to the user after that.