Docs menu
Getting started
API
Account
Errors and Quotas
One error envelope, specific codes, honest messages, and clear reset times.
Every error response uses one envelope: an error object with a human-readable message, a machine-readable type, and a specific code. Branch on code; show the message to humans.
{
"error": {
"message": "Rate limit exceeded (10 requests per minute on the free plan). You can upgrade at https://dipoleml.com/pricing for higher limits.",
"type": "rate_limit_error",
"code": "requests_per_minute"
}
}#Status codes
| Status | code | Meaning and what to do |
|---|---|---|
| 400 | invalid_request_error | Malformed JSON or an invalid parameter. Fix the request. |
| 401 | invalid_api_key | Missing, malformed, or revoked key. Check the Authorization header; recreate the key if it was revoked. |
| 401 | key_expired | The key passed its expiration. Create a new key (dashboard or management API); unaffected keys keep working. |
| 402 | insufficient_credits | API key with an empty credit balance. Top up; the message includes the link. See API Credits. |
| 402 | key_limit_reached | The key hit its per-key spend cap. Raise or remove the limit (dashboard or management API); other keys and the balance are unaffected. See Management Keys. |
| 404 | model_not_found | Unknown model name. Use exactly Raven Flash or Raven Max; the error lists valid ids. |
| 429 | requests_per_minute | Too many requests in one minute. Back off and retry; the message states the limit. |
| 429 | window_6h_limit | Plan usage window exhausted for this model. The message gives the limit and the exact reset time. Wait for the reset or upgrade. |
| 429 | window_weekly_limit | Same, for the weekly window. |
| 429 | free_max_credit_exhausted | The free tier's one-time Raven Max trial credit is used up. Other tiers are unaffected. |
| 500, 502, 503 | api_error | Something failed serving the request. Safe to retry with backoff if nothing was delivered yet. |
#Usage windows
Plan-based access (DCode and the raven app) enforces two rolling allowances per model: a 6-hour window aligned to UTC hours 00, 06, 12, and 18, and a weekly window that resets Monday 00:00 UTC. The full allowance table lives in Plans and Usage. When a window is exhausted, the 429 message names the limit and the exact reset time, so a well-behaved client can simply wait until then.
API-key requests are not subject to the 6-hour and weekly windows. They are limited by your credit balance plus a per-minute rate limit that keeps the service fair for everyone.
#Writing a backoff loop
import os, time
from openai import OpenAI, RateLimitError
client = OpenAI(
base_url="https://api.dipoleml.com/v1",
api_key=os.environ["RAVEN_API_KEY"],
)
def complete(messages, attempts=4):
for i in range(attempts):
try:
return client.chat.completions.create(
model="Raven Flash", messages=messages
)
except RateLimitError:
if i == attempts - 1:
raise
time.sleep(2 ** i) # 1s, 2s, 4s
resp = complete([{"role": "user", "content": "Ping"}])
print(resp.choices[0].message.content)Retry 429 and 5xx with exponential backoff. Do not retry 400, 401, 402, or 404; those need a human or a config change, not another attempt.