Guides
Errors
Failures use one JSON shape and a small set of stable codes. The HTTP status tells you whether to fix the request, the plan or your retry loop.
The error envelope
Every failed REST call returns an object with code, a human-readable error, and optional details. code is the field to branch on; the message can change.
{
"code": "insufficient_credits",
"error": "not enough credits",
"details": {
"required": 34,
"available": 12
}
}details is free-form per code. For insufficient_credits it carries required and available, which is enough to decide whether to pause or top up.
Codes and statuses
| Code | Status | Meaning |
|---|---|---|
invalid_request | 400 | The body is not valid JSON, exceeds 1 MiB, or fails the Tool's schema. |
forbidden_scope | 403 | The key does not carry the scope the Tool requires. |
forbidden_role | 403 | The caller's role cannot perform this action in the workspace. |
not_found | 404 | The Tool or the referenced record does not exist. |
idempotency_conflict | 409 | The same idempotency key was reused with different arguments. |
job_expired | 410 | The queued job has expired and its result is no longer stored. |
platform_not_supported | 422 | The platform does not support this Tool. |
unsupported_duration | 422 | The post is longer than the Tool supports (180 seconds for analysis). |
feature_not_in_plan | 402 | The workspace's plan does not include this capability. |
quota_exceeded | 402 | A plan quota, such as channels or tracked creators, is full. |
insufficient_credits | 402 | The workspace cannot cover the Tool's maximum price. |
provider_unavailable | 502 | An upstream provider failed. Retry with backoff. |
internal | 500 | An unexpected failure. Retry once; report it if it repeats. |
Validation comes from the Tool's JSON Schema, but the message is not a field-level report. A missing required field returns invalid_request; check the Tool's schema when a call is rejected.
Example: a missing argument
get_post requires a public post URL. Sending an empty object fails validation before the Tool runs, so no credits are held.
curl -X POST https://api.cuekoo.com/openapi/v1/tools/get_post \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'{
"code": "invalid_request",
"error": "enter a valid HTTPS post URL"
}Errors over MCP
MCP separates transport failures from Tool failures. A bad key, a forbidden workspace or an MCP protocol error is an HTTP error before a tool is called. Once a Tool runs, its failure comes back inside the MCP result:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"isError": true,
"content": [
{
"type": "text",
"text": "{"code":"insufficient_credits","error":"not enough credits"}"
}
]
}
}Parse the text content as the same envelope. MCP clients render isError as a failed tool call rather than a failed request, so an agent can explain the problem instead of disconnecting.
Retry rules
- Retry with backoff:
provider_unavailable(502) andinternal(500). - Do not retry unchanged:
invalid_request,forbidden_scope,forbidden_role,not_found,platform_not_supported,unsupported_duration,job_expired,feature_not_in_plan,quota_exceededandinsufficient_credits. - Reconcile:
idempotency_conflictmeans a retry reused a key with a different body. Reuse the original body or start a new request.
Failed calls release their credit hold, so a retry after a failed Tool charges once, not twice. Sending Idempotency-Key with a UUID on mutating calls makes a network retry safe even when the first response was lost.
Related
- Authentication: 401 versus 403.
- Credits: 402 codes and hold release.
- Queued jobs:
job_expiredand status polling.