Hoveydai

Errors

The error format, every code with its cause and fix, retrying, errors inside a stream and what to send to support.

Reading time: 6 min

The error format

Every failed /v1 request returns a JSON body with a single error object, whatever the status, and the response always carries an x-request-id header:

JSON
{  "error": {    "message": "'temperature' must be between 0 and 2.",    "type": "invalid_request_error",    "param": "temperature",    "code": "invalid_value",    "request_id": "6f1d0c52-8a0e-4b0f-9d57-3c1a7a2f4e10"  }}
FieldMeaning
codeA stable, machine-readable reason. Branch on this in your code.
typeThe group of the error: invalid_request_error (your request is wrong), authentication_error (the key), insufficient_quota (credit), permission_error (your plan or the content), rate_limit_error (too many requests) or api_error (a problem on our side or the model's).
messageA sentence for people, in English. It may be reworded, so never match on it.
paramThe request field that caused the error, such as model or messages, or null.
request_idThe id of this call. It equals the x-request-id header.

Some errors add a field: wallet_balance_units on 402 (your balance), quota_code on quota_exceeded and suggested_models on model_does_not_support_images.

Three more typical responses:

JSON
{"error": {"message": "Missing credentials. Send 'Authorization: Bearer <your Hoveydai API key>'.", "type": "authentication_error", "param": null, "code": "invalid_api_key", "request_id": "..."}}
JSON
{"error": {"message": "Rate limit reached (60 per minute). Retry after 3 seconds.", "type": "rate_limit_error", "param": null, "code": "rate_limit_exceeded", "request_id": "..."}}
JSON
{"error": {"message": "The model is temporarily unavailable or busy. Please retry shortly.", "type": "api_error", "param": null, "code": "model_unavailable", "request_id": "..."}}

Every error code

StatusCodeWhat happenedUsual causeWhat to do
400invalid_jsonThe body could not be read as a JSON object.An empty body, a trailing comma, or a body that is not JSON.Check the body with jq . and send Content-Type: application/json.
400missing_required_parameterA required field is absent.model, messages or a message's role or content is missing.Add the field named in param.
400invalid_typeA field has the wrong type.For example messages is a string, or stream is "true" instead of true.Send the type the message asks for.
400invalid_valueA field is present but its value is not allowed.temperature outside 0 to 2, top_p outside 0 to 1, an empty messages list, more than 4 stop strings.Bring the value in range, as the message states.
400unsupported_valueThe value is valid in general but not supported here.n other than 1, or a role that is not system, developer, user or assistant.Use n: 1 and one of the supported roles.
400invalid_image_urlAn image part could not be used.A remote http(s) URL, bad base64, a file over 20 MB or a type other than PNG, JPEG, WebP and GIF.Send the image inline as data:image/png;base64,... within these limits.
400too_many_imagesThe request holds more than 8 images.Many image_url parts in one request.Split them over several requests.
401invalid_api_keyThe key is missing, wrong or deleted.No Authorization header, a typo, or a key you deleted.Send Authorization: Bearer hvd_... with a key that is listed under Keys in the dashboard.
401token_expiredA dashboard session token has expired.Calling the API with a login token instead of a key.Use an API key, or sign in again.
401session_revokedThe dashboard session was signed out.Signing out elsewhere invalidated the token.Use an API key, or sign in again.
402insufficient_creditsYour balance cannot cover this request.The model is paid and the wallet is empty (free models never need a balance).Add credit to the wallet or upgrade the plan; wallet_balance_units shows what is left.
402quota_exceededA plan limit is reached.The daily or monthly image allowance; quota_code says which.Wait for the limit to reset or upgrade the plan.
403model_requires_paid_planThis model is not on your plan.A free plan calling a paid-only model.Pick another model, upgrade, or add credit to the wallet.
403content_blockedThe model's content filter refused the request.The prompt or the file triggered the filter.Change the input; resending it unchanged gives the same result.
404model_not_foundThere is no such model for you.A typo in model, a model removed from the list, or one you cannot use.Copy an id from GET /v1/models, or use auto.
404unknown_urlNo such address under /v1.A wrong path, such as /v1/embeddings.Use POST /v1/chat/completions or GET /v1/models.
405method_not_allowedThe path exists, but not with this HTTP method.GET on /v1/chat/completions, for example.Use the method in the Allow header of the response.
413request_too_largeThe body is bigger than 40 MB.Large base64 images.Shrink or drop images, or send fewer messages.
422context_length_exceededThe input and the requested output do not fit the context.A long history, or a large max_tokens.Drop old messages, shorten the input, or lower max_tokens.
422model_does_not_support_imagesThe model cannot read images.An image_url part sent to a text-only model.Use a model from suggested_models, or one with supports_vision in /v1/models.
429rate_limit_exceededYour key sent more requests than its per-minute limit.A loop or a burst; the default limit is 60 requests a minute per key.Wait Retry-After seconds, then retry; spread requests out.
429too_many_concurrentToo many of your requests are running at the same moment.By default 2 at once on the free plan and 4 on paid plans.Wait for one to finish, or retry after Retry-After.
500internal_errorSomething failed inside Hoveydai.A bug on our side.Retry once; if it repeats, write to support with the request_id.
502provider_errorThe model's provider failed or returned an empty answer.An upstream fault.Retry with backoff; if it persists, write to support.
503model_unavailableThe model is busy or temporarily down.Heavy load on the provider.Retry after Retry-After, or use another model.
503service_unavailableThe service cannot take requests right now.The catalog is not ready, or the provider side is being fixed.Retry after Retry-After.
504provider_timeoutThe model took too long to answer.A long answer or a slow provider.Retry, ask for a shorter answer, or use stream: true.

Which errors to retry

Retry only 429, 502, 503 and 504. Every other 4xx repeats itself until you change the request, and 500 deserves one retry at most.

  • If the response has a Retry-After header, wait that many seconds. It is present on 429 and 503.
  • Otherwise wait 1 second, then 2, 4 and 8, and stop after 4 or 5 attempts. Add a little randomness so many clients do not retry together.
for wait in 1 2 4 8; do  code=$(curl -s -o reply.json -w "%{http_code}" https://api.hoveydai.ir/v1/chat/completions \    -H "Authorization: Bearer $HOVEYDAI_API_KEY" -H "Content-Type: application/json" \    -d '{"model": "MODEL_ID", "messages": [{"role": "user", "content": "Hello"}]}')  case $code in 429|502|503|504) sleep $wait ;; *) break ;; esacdonecat reply.json

Errors in a streaming response

What happens depends on when the failure comes:

  • Before the first chunk (a bad key, an unknown model, no credit, a provider that fails at once): you get an ordinary HTTP error with the status and JSON body described above. Handle it as for a request without stream.
  • After the first chunk: the HTTP status is already 200, so the error arrives as one more event, data: {"error": {...}}, with the same fields. The stream then ends without data: [DONE]. Keep the text received so far, check each event for an error key, and decide whether to retry the whole request.

A connection that is cut with no error event also means an unfinished answer: a stream is complete only after data: [DONE].

Rate limit headers

Responses to a rate-limited key carry these headers, and a browser script can read them too:

HeaderMeaning
x-ratelimit-limit-requestsThe requests allowed in the current window.
x-ratelimit-remaining-requestsHow many are left in this window.
x-ratelimit-reset-requestsTime until the window resets, such as 42s.
Retry-AfterOn 429 and 503: the seconds to wait before retrying.

The x-ratelimit-* headers can be absent on some deployments, so do not depend on them. Rely on 429 and Retry-After.

What to send to support

Write to support@hoveydai.ir and include:

  1. The request_id from the error body, or the x-request-id header. It lets us find the exact call.
  2. The time of the call and your time zone.
  3. The model id you used.
  4. The status and code you received. Never include your API key.

Did this page not help? Tell us.