reference
Errors and limits
Errors use the OpenAI envelope, so existing client error handling works:
{
"error": {
"message": "Your credit balance is empty. Add credits at ...",
"type": "insufficient_quota",
"param": null,
"code": "insufficient_credit"
}
}Codes
| status | code | meaning | retry? |
|---|---|---|---|
| 400 | invalid_json | The body was not valid JSON. | No |
| 400 | missing_text | /v1/restyle was called without a non-empty text. | No |
| 400 | missing_question | /v1/fanout was called without a non-empty question. | No |
| 400 | input_too_large | Over the input bound for the model you named: 6,000 characters for a restyle, which you send a section at a time, or 2000 for a fan-out question. The message names the length you sent. | No |
| 400 | missing_state | /v1/systemone was called without a state. | No |
| 400 | invalid_questions | A question in a /v1/systemone request does not follow the schema: an unknown type, missing instructions, or criteria of the wrong shape or size. param names the question. | No |
| 400 | input_too_long | Over the 4,096-token context: a restyle block with no paragraph break in it, or a /v1/systemone state and questions that are too long together. Split it and send it again. | No |
| 400 | wrong_endpoint_for_model | The model named does not do the work this endpoint does — a rewrite model at /v1/fanout. Served badly it would return a plausible-looking answer, so it is refused. | No |
| 401 | invalid_api_key | Missing, malformed, unknown or revoked key. | No |
| 402 | insufficient_credit | The account balance is empty. Add credit, or turn on auto top-up. | After topping up |
| 402 | key_spend_limit_reached | This key hit its lifetime cap. Other keys are unaffected. | After raising it |
| 403 | model_not_permitted | The key’s allowlist does not include this model. | No |
| 404 | model_not_found | No such model id. | No |
| 404 | model_not_available | The model is in the catalogue but not serving yet. | No |
| 502 | empty_generation | A fan-out produced nothing usable for that question, so there is no list to return. | Once, then rephrase |
| 429 | capacity_saturated | Our capacity is full, or ran out while your request was running. When extra capacity is starting, the message says so and Retry-After is 30 seconds; otherwise it is 5. Nothing is charged, and a restyle never comes back half done: it is either complete or this error. | Yes, after Retry-After |
| 502 | upstream_error | The model returned an error. | Yes, with backoff |
| 502 | upstream_unreachable | The model could not be reached. | Yes, with backoff |
| 503 | no_capacity | No capacity is available. A problem on our side, not with your request. | Yes, with backoff |
| 504 | timeout | The model took too long. | Yes |
In short: retry 429 after the Retry-After header, and 5xx with exponential backoff and jitter — with the exception of empty_generation, where the model ran and simply produced nothing usable, so one retry is worth it and a loop is not. Do not retry 4xx, nothing about the request will have changed.
Asking about a specific request
Every API response carries a request ID: as id in the body and as the X-Request-Id header, on errors as well as successes. Chat completions use their chatcmpl- id. Keep it with anything you might want to ask us about, and quote it when you do.
You can look a request up yourself, with any key on the same account:
curl https://meragpt.com/v1/requests/req_4f1c9a0b2e7d6c5a3b8e9f01 -H "Authorization: Bearer $MERAGPT_API_KEY"{
"id": "req_4f1c9a0b2e7d6c5a3b8e9f01",
"object": "request",
"model": "restyler-1",
"status": "succeeded",
"latency_ms": 4210,
"usage": { "input_tokens": 412, "output_tokens": 377, "cost_usd": "$0.000077" },
"detail": {
"rewritten": 3,
"total": 4,
"blocks": [
{ "index": 2, "words": 61, "status": "unchanged", "reason": "invented" }
]
}
}It tells you what happened — which paragraphs were rewritten or left unchanged and why, tokens, cost, latency and any error — but never what was said: we do not store the text you send or the text we return. See our privacy policy.
Failed requests are not charged
A request that fails before the model generates anything costs nothing. It is still recorded, at zero cost, so a failing integration is visible on your usage dashboard instead of only in our logs.
Limits
| limit | value |
|---|---|
| Request body, restyle | 6,000 characters per request |
| Single block, restyle | ~1,150 words |
| Question, fan-out | 2000 characters |
| Brands and category, fan-out | Up to 12 brands; each brand and the category up to 100 characters |
| Queries returned, fan-out | Up to 6, after near-duplicates are dropped |
| Context window | 4,096 tokens, prompt and completion together |
| Request timeout | 180 seconds per block |
| Playground, signed out | 10 runs a day per IP, 2,000 characters each |
Per-key concurrency limits apply so that one caller cannot occupy the whole fleet. If you are planning something high-volume, email hello@meragpt.com first and we will make sure the capacity is there.