Errors and limits
Interpret error responses from the Engy API, handle capacity limits, and decide when to retry.
This page describes the error format of the Engy API, the status codes that it returns, and the limits that apply to requests. It is intended for developers who build reliable integrations.
Error format
On the OpenAI-compatible endpoints, an error response has the following format:
{
"error": {
"message": "insufficient credits",
"type": "insufficient_quota",
"param": null,
"code": 402
}
}| Field | Description |
|---|---|
message | A description of the error. |
type | The error type. See the table in the next section. |
param | The request parameter that caused the error, if applicable. Otherwise null. |
code | The HTTP status code. |
On /v1/messages, errors use the Anthropic format:
{
"type": "error",
"error": {"type": "invalid_request_error", "message": "..."}
}Every response, including an error response, contains the X-Engy-Request-Id header. Include its value when you contact support.
For server errors (status 500 and above), the message is generic and ends with the request ID, for example: service temporarily unavailable; please retry, or report request_id ....
For errors during a streamed response, see Streaming.
Status codes
| Status | OpenAI type | Anthropic type | Cause | Retry |
|---|---|---|---|---|
400 | invalid_request_error | invalid_request_error | The request is invalid. For example, the prompt exceeds the context window, a parameter has an invalid value, or the model does not accept the input type. | No. Correct the request. |
401 | authentication_error | authentication_error | The API key is missing or invalid. | No. Check the key. |
402 | insufficient_quota | api_error | Your available balance does not cover the request. | After you add credits or reduce max_tokens |
404 | not_found_error | not_found_error | The model does not exist or is currently unavailable. | No. Check the model ID. |
413 | invalid_request_error | request_too_large | The media in the request exceed the size or count limit. | No. Reduce the media. |
429 | rate_limit_error | rate_limit_error | All capacity for the model is busy, or you reached a concurrency limit. | Yes, with backoff |
500 | internal_error | api_error | An internal error occurred. | Yes |
502 | upstream_error | api_error | The model server returned an error. | Yes |
503 | service_unavailable | overloaded_error | No worker can meet the request requirements, such as provider.zdr. | Yes, later, or relax the requirement |
504 | upstream_error | api_error | The model server timed out. | Yes |
Context window errors
A request fails with status 400 if the prompt alone, or the prompt plus max_tokens, exceeds the model's context window. The message states the token counts:
prompt is 300512 tokens, which exceeds the model's context window of 262144; reduce the promptOn /v1/messages, the message uses the Anthropic wording: prompt is too long: N tokens > M maximum.
To resolve the error, shorten the prompt or reduce max_tokens. For the context window of each model, see Models and pricing.
Capacity and concurrency limits
The Engy API does not limit requests or tokens per minute, and it does not return rate limit headers. Status 429 indicates one of the following conditions:
| Message | Meaning |
|---|---|
capacity exhausted, retry shortly | All workers that serve the model are busy. |
account concurrency limit exceeded, retry shortly | Your account has too many requests in progress. |
per-model concurrency limit exceeded, retry shortly | Your account has too many requests in progress for this model. |
Non-streaming 429 responses from /v1/chat/completions, /v1/completions, and /v1/responses include a Retry-After header.
Retry requests
Retry requests that fail with status 429, 500, 502, 503, or 504. Use exponential backoff with jitter:
import os
import random
import time
import httpx
RETRYABLE = {429, 500, 502, 503, 504}
def create_completion(body, max_attempts=5):
for attempt in range(max_attempts):
response = httpx.post(
"https://api.engy.ai/v1/chat/completions",
headers={"Authorization": f"Bearer {os.environ['ENGY_API_KEY']}"},
json=body,
timeout=600,
)
if response.status_code not in RETRYABLE or attempt == max_attempts - 1:
response.raise_for_status()
return response.json()
retry_after = response.headers.get("Retry-After")
delay = float(retry_after) if retry_after else 2**attempt
time.sleep(delay + random.uniform(0, 1))
result = create_completion(
{"model": "glm-5.2", "messages": [{"role": "user", "content": "Hello"}]}
)
print(result["choices"][0]["message"]["content"])The OpenAI and Anthropic SDKs retry these errors automatically. You can configure the number of retries with the max_retries client option.
If errors persist, check the status page for incidents that affect the service.
Billing for failed requests
Engy does not charge for a request that fails. This applies to errors from the model server, timeouts, and capacity errors. If you close the connection during a streamed response, Engy stops generation and does not charge for the request.
Request limits
| Limit | Value |
|---|---|
| Media per request | 12 MiB decoded and 100 parts. For details, see Image input. |
top_logprobs | 30 |
Scored tokens on /v1/completions | 1,024. For details, see Raw prompts and log probabilities. |
| Time without output from the model | 600 seconds for most models, up to 1,200 seconds for long-context models. After that, the request fails with status 504. |
For non-streaming requests that run longer than 15 seconds, Engy sends whitespace before the response body to keep the connection open. The HTTP status is then 200, and a late error appears in the response body. JSON parsers ignore the leading whitespace. If your requests are long, use streaming or check the body for an error field.