Errors
Every status code the API returns, what it means, and how to react to it.
The error envelope
Errors share one shape. code is -1, message is human-readable, and error repeats the message so the body reads like a normal REST error. Some errors add extra fields that tell you what to do next.
{
"code": -1,
"message": "\"input\" is required",
"error": "\"input\" is required"
}Status codes
400 Bad Request
The request never reached the model. Nothing was billed.
| Message | Cause |
|---|---|
Request body must be JSON | The body could not be parsed. |
Request body must be a JSON object | The body was valid JSON but not an object. |
"input" is required | input (or state) was missing or empty. |
At least one question is required | questions was missing or empty. |
Question "<key>" requires a "prompt" (or "instructions") string | A question had no prompt. |
Question "<key>" of type "choice" requires a "criteria" object, ... | A choice question had no criteria. |
Question "<key>" of type "score" requires a "criteria" array, ... | A score question had no criteria. |
Question "<key>" has an unsupported type. Use one of: choice, score, noul | The type was not recognised. |
401 Unauthorized
| Message | Cause |
|---|---|
Missing API key. Pass it as "Authorization: Bearer sk-..." | No bearer token on the request. |
Invalid API key | The key does not exist, was deleted, or is disabled. |
402 Payment Required
The account has no usable credits.
{
"code": -1,
"message": "Insufficient credits",
"error": "Insufficient credits",
"remaining_credits": 0
}Buy a credit pack to continue. See Limits & credits.
429 Too Many Requests
The daily allowance is used up. See Limits & credits for the full rules.
{
"code": -1,
"message": "You have reached the daily free limit of 100 decisions. Buy credits to lift it.",
"error": "You have reached the daily free limit of 100 decisions. Buy credits to lift it.",
"daily_limit": 100,
"reset_at": "2026-11-01T09:14:22.000Z",
"remaining_credits": 812,
"upgrade_path": "/settings/credits"
}500 Internal Server Error
The service could not complete the call — for example Jev decision failed unexpectedly, or Jev upstream is not configured. Nothing was billed. Retry after a short delay; if it persists, contact support with the request id.
502 Bad Gateway
The upstream model rejected the request, or answered in a way the API could not turn into a decision. The message carries the upstream status and body so you can see what the provider said. Nothing was billed.
Handling errors in code
const response = await fetch('https://jevmodel.io/api/v1/decisions', options);
const payload = await response.json();
if (!response.ok) {
switch (response.status) {
case 400:
throw new Error(`Bad request: ${payload.message}`);
case 401:
throw new Error('The API key is missing or invalid.');
case 402:
throw new Error('Out of credits.');
case 429:
throw new Error(`Rate limited until ${payload.reset_at}.`);
default:
throw new Error(`Jev API error ${response.status}: ${payload.message}`);
}
}Retrying
400,401, and402will not succeed on a retry. Fix the request, the key, or the balance first.429succeeds afterreset_at.500and502are worth retrying with exponential backoff. Since a failed call is not billed, a retry costs you nothing beyond the upstream call.