Errors
Errors use standard HTTP status codes and a JSON body with a stable code. Branch on code; the message is for people and may change.
response
{
"error": {
"origin": "kyvalt",
"code": "minimum_discount_not_met",
"requestId": "80b36df0-3d61-4f7d-8240-e0144e33260e",
"message": "No offer for 'deepseek-v4-pro' meets the requested minimum discount of 95% ...",
"details": { "model": "deepseek-v4-pro", "min_discount_pct": 95 }
}
}originiskyvaltwhen Kyvalt rejected the request, andupstreamornetworkwhen the seller's provider or the connection to it failed.requestIdmatches thex-request-idheader and the entry in Usage logs.detailsis optional and depends on the code.
Error codes
| Status | Code | Meaning and what to do |
|---|---|---|
| 400 | invalid_request | The body is not valid for the endpoint, a field such as max_price_per_1m is invalid, or two different keys were sent. details.field names the field when known. |
| 400 | invalid_min_discount_header | X-Min-Discount is not a whole number from 0 to 100. |
| 400 | prompt_rejected | The content guard blocked the prompt. Not charged. Do not retry the same prompt. |
| 401 | authentication_failed | The key is missing, unknown or revoked. |
| 402 | insufficient_credit | Available balance is below the hold for this request. Add funds or lower max_tokens. |
| 403 | model_not_allowed | This key may not use the model. |
| 404 | model_not_found | The model ID is not on Kyvalt. Check GET /v1/models. |
| 404 | no_sellers_for_model | The model is listed but no offer can serve it right now. Retry later or use another model. |
| 404 | minimum_discount_not_met | No offer meets your discount floor. Lower the floor or retry later. |
| 404 | max_price_exceeded | No offer is under your max_price_per_1m. |
| 429 | rate_limited, capacity_exhausted | Too many requests at once. Wait for the retry-after header, then retry. |
| 502 | transport_unavailable | The connection to the seller dropped. Not charged; safe to retry. |
| 503 | vendor_price_unavailable, admission_unavailable | Temporary. Retry with backoff. |
| 504 | deadline_exceeded | The request took too long. Not charged. Retry, or lower max_tokens. |
Retrying
Kyvalt already retries other sellers inside a single request, so a retry from your side is only needed for 429, 5xx and no_sellers_for_model. Use exponential backoff starting at one second, and respect retry-after when it is present. Do not retry 400, 401, 402 or 403 without changing the request.