All non-2xx responses from the Knouds API return a JSON body. At minimum it contains error (a human-readable message) and code (a machine-readable constant). Some errors include additional context fields to help you diagnose the problem without guessing.
{ "error": "<message>", "code": "<CODE>", ...context }
Error reference
| HTTP status | Code | Meaning |
|---|
400 | INVALID_INPUTS | The request body is malformed or missing required fields. Check that inputs is a non-array object. |
400 | INVALID_SLUG | The workflow slug or model internalName in the URL contains invalid characters. Slugs must be lowercase letters, digits, and hyphens only. |
400 | INVALID_BODY | Request body is not valid JSON or is missing required fields. |
400 | INVALID_CAPABILITY | A capability string supplied at key creation is malformed (unknown verb, invalid slug pattern). |
400 | ASYNC_NOT_SUPPORTED | ?async=true was used on an endpoint whose provider doesn’t support polling-based async (Fal-backed, Anthropic, HTTP-without-polling). Use sync mode (omit ?async=true). |
401 | (no code) | The x-api-key header is missing, the key has been revoked, or the key is invalid. |
401 | LEGACY_KEY_RETIRED | Pre-Phase-11 key (created before May 2026). Regenerate at the Developer Dashboard. See Migration from scopes. |
402 | INSUFFICIENT_CREDITS | Your account does not have enough credits to complete the request. Top up your credit balance to continue. |
402 | grant_exhausted | Your trial grant for this model has been fully used. Topping up credits will not unlock further access — you must upgrade your tier. |
403 | CAPABILITY_DENIED | Your key’s capability set does not cover this endpoint. Response includes required indicating which capability would have passed. |
403 | CAPABILITY_ABOVE_CEILING | At key-creation time you tried to grant a capability your tier doesn’t allow. Response includes attempted. |
403 | API_KEY_ACCESS_DENIED | Free tier — upgrade to Pro to create API keys. |
403 | MODEL_TIER_REQUIRED | The model you are trying to run requires a higher plan tier than your account currently holds. |
403 | WORKFLOW_CAP_REACHED | Free user trying to create a workflow above the per-tier cap (maxWorkflows: 1 for Free). Upgrade to Pro for unlimited. |
404 | MODEL_NOT_FOUND | The internalName in the URL does not match any enabled registry model. |
404 | EXECUTION_NOT_FOUND | The execution id (UUID) doesn’t resolve to a row owned by you. |
404 | (message) | The workflow slug in the URL does not match any workflow you own. |
429 | RATE_LIMIT_EXCEEDED | You have exceeded the per-minute request limit for your tier. Check the Retry-After header. |
500 | EXECUTION_FAILED | A provider call failed. The error field describes the cause. Retry with exponential back-off. |
500 | PROVIDER_SUBMIT_FAILED | Async submit hit upstream 4xx/5xx — surfaced synchronously so you don’t wait on a stuck processing row. Body includes providerStatus + providerBody. |
500 | PROVIDER_RESPONSE_INCOMPLETE | Polling completed but the provider’s response didn’t contain the expected output (rare — transient provider issue or a misconfigured model). Credits NOT deducted. |
The two distinct 402 responses
Two different situations both return 402, and they require different responses:
INSUFFICIENT_CREDITS — you have a valid plan and the model is accessible, but your credit balance is too low. Go to Settings → Billing and top up your credits.
grant_exhausted — your plan includes a limited trial grant for this model (for example, 1 free lifetime generation on a Free plan) and you have used it all. Topping up credits will not help here. You need to upgrade to a higher plan tier.
If you receive grant_exhausted, adding credits to your account will not resolve the error. The grant is a tier-level feature, not a credit-level one. Upgrade your plan to regain access.
CAPABILITY_DENIED payload
When your key lacks the required capability, the response tells you exactly which one would have passed:
{
"error": "Insufficient capability",
"code": "CAPABILITY_DENIED",
"required": "model:run"
}
Use required to decide whether to regenerate your key with broader capabilities (capped by your tier) or upgrade your tier.
Handling errors in code
const response = await fetch(url, options);
if (!response.ok) {
const err = await response.json();
if (response.status === 429) {
const retryAfter = parseInt(response.headers.get('Retry-After') || '10', 10);
// Wait and retry
} else if (err.code === 'INSUFFICIENT_CREDITS') {
// Prompt user to top up credits
} else if (err.code === 'grant_exhausted') {
// Prompt user to upgrade plan — credits won't help
} else if (err.code === 'CAPABILITY_DENIED') {
console.error(`Need capability: ${err.required}`);
} else if (err.code === 'LEGACY_KEY_RETIRED') {
console.error('Regenerate your key at https://knouds.ai/app/api/keys');
}
}