Error format
Errors are returned with a non-2xx HTTP status and a JSON body with an error field. Depending on where the error comes from, error is either a string or an object:
Gateway checks: a string
Validation, authentication, insufficient balance and internal errors:
{ "error": "Missing required fields: model, messages"}Key limits and provider errors: an object
Per-key monthly limits and errors passed through from the model provider use the OpenAI-style object with message and a code:
{ "error": { "message": "Monthly spend limit reached for this API key", "type": "insufficient_quota", "code": "key_monthly_limit" }}{ "error": { "message": "Rate limit exceeded, please retry shortly", "code": 429 }}Handle both shapes when you parse errors yourself:
// Works for both error shapes returned by Promptixfunction errorMessage(body) { if (typeof body?.error === 'string') return body.error; return body?.error?.message ?? 'Unknown error';} const res = await fetch('https://promptix.tn/api/v1/chat/completions', { /* ... */ });if (!res.ok) { const body = await res.json().catch(() => null); const code = typeof body?.error === 'object' ? body.error.code : undefined; throw new Error(`${res.status}${code ? ` ${code}` : ''}: ${errorMessage(body)}`);}Status codes
| Status | Meaning | Retry |
|---|---|---|
| 400 | Invalid request: the body is not JSON (Invalid JSON body), model or messages is missing or has the wrong type, or the provider rejected the request (unknown model, invalid parameter, prompt too long). | No |
| 401 | Missing, malformed, unknown or revoked API key, or deactivated account. See Authentication. | No |
| 402 | Balance below 0.100 TND (Insufficient credits), or the key reached its monthly limit (code key_monthly_limit). | No |
| 404 | The provider could not find the requested model or resource. | No |
| 413 | The request is too large for the model. Shorten the prompt or pick a model with a longer context. | No |
| 422 | The provider could not process the request as sent (for example an unsupported parameter combination). | No |
| 429 | The upstream provider is rate limiting this model. Retry with exponential backoff, or switch model. | Yes |
| 500 | Unexpected error in Promptix or upstream. Retry with backoff; contact support if it persists. | Yes |
Insufficient credits
A request is accepted only if your balance is at least 0.100 TND when it starts. Otherwise:
{ "error": "Insufficient credits. Please top up your account."}The cost of a request is deducted after it completes, so a long request that starts with a small balance can take it slightly below zero. Top up to continue; requests work again as soon as the payment is confirmed. Promptix emails you when your balance drops below 5 TND, so you can top up before this happens (you can turn this alert off in Settings).
Monthly key limit reached
When a key has a monthly limit and its spend since the first day of the month (UTC) has reached it, requests with that key return 402 with "code": "key_monthly_limit" and "type": "insufficient_quota". Nothing is billed. Raise or remove the limit in API keys, use another key, or wait for the next month. Details in Authentication.
Rate limits
Promptix does not add a requests-per-minute limit of its own. Throughput is limited by each model's provider: when a provider throttles, you receive its 429. Free models have much tighter limits than paid ones.
- Retry 429 and 5xx responses with exponential backoff and jitter (for example 1 s, 2 s, 4 s, then give up).
- Do not retry 400, 401, 402, 404, 413 or 422: the same request will fail again.
- For bulk jobs, cap concurrency (a few parallel requests) rather than sending everything at once.
- If one model stays throttled, fall back to an equivalent model from another provider.
Errors while streaming
Errors detected before a stream starts use the status codes above. If the provider fails after streaming has begun, the status is already 200; Promptix sends a final event and closes the stream without data: [DONE]:
data: {"error":{"message":"Streaming failed","type":"stream_error"}}See Streaming.
Handling errors with the OpenAI SDKs
The SDKs raise typed exceptions from the HTTP status and retry 408, 409, 429 and 5xx responses automatically (twice by default). A 402 is not retried.
import osimport openaifrom openai import OpenAI client = OpenAI( base_url="https://promptix.tn/api/v1", api_key=os.environ["PROMPTIX_API_KEY"], max_retries=3, # retries 408, 409, 429 and 5xx with exponential backoff timeout=120,) try: completion = client.chat.completions.create( model="openai/gpt-4o-mini", messages=[{"role": "user", "content": "Hello"}], )except openai.AuthenticationError: print("401: check PROMPTIX_API_KEY")except openai.RateLimitError: print("429: the provider is throttling, retry later")except openai.APIStatusError as e: if e.status_code == 402: body = e.response.json() err = body.get("error") if isinstance(err, dict) and err.get("code") == "key_monthly_limit": print("402: this key reached its monthly limit") else: print("402: balance too low, top up in the dashboard") else: print(e.status_code, e.message)Timeouts
A request, including a stream, can run for up to 300 seconds on Promptix. Set your client timeout a little above the longest answer you expect, and use streaming for long generations so the connection is never idle.
Need help?
If an error persists, contact support with the time of the request, the model and, when you have it, the generation id.