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 retry400,401,402, or403— 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.