Skip to content

API Reference

Errors

The single Clipia API error format — type, code and message fields, the table of HTTP statuses and codes, what to retry, and how to read message.

Every REST API error uses the same format: an error object with type, code and message fields. The HTTP status sets the error class; code is the machine-readable reason. Only transient errors are worth retrying after a pause: 409 request_in_progress, 429, 500 and 503.

{
  "error": {
    "type": "authentication_error",
    "code": "invalid_api_key",
    "message": "Invalid or revoked API key."
  }
}

Branch on code. The message field is meant for humans and can change. For 400 invalid_request, message carries a short detail such as prompt_required or webhook_url_invalid; the full list for generation submit is on Submit a generation. Most messages come in English, but some input-check refusals (for example, a prompt that is too short or incompatible references) come in Russian regardless of the header. For 402 errors and music-settings refusals, the Accept-Language: ru header switches the text to Russian.

Sometimes error includes retry_after_ms or retry_after_seconds — a hint for when to retry.

Responses that never reach a route handler use the same format: 400 invalid_request for a body that is not valid JSON, 415 unsupported_media_type for a body type the server doesn't parse (for example, application/xml), 413 request_too_large for a body over 10 MB and 404 not_found for an unknown path under /v1/ (including a preflight OPTIONS from a disallowed origin). These responses never expose internal server paths.

Codes

HTTPcodetypeWhenRetry
400invalid_requestinvalid_request_errorinvalid body, parameters or ID; the reason is in messageno, fix the request
401invalid_api_keyauthentication_errorthe key is missing, wrong, revoked or expiredno
402insufficient_creditsbilling_errornot enough creditsafter topping up
402subscription_requiredbilling_erroran active subscription is required: the Public API condition for live keys, or credits frozen until the plan is renewedafter subscribing
402insufficient_quotabilling_errorthe request doesn't fit the key's budget, see Managing keysonce there is room in the budget
403insufficient_scopepermission_errorthe key lacks the required permissionno
404not_foundinvalid_request_errorno such model (model_not_found) or request (request_not_found)no
409idempotency_key_reuseidempotency_errorthe same Idempotency-Key with a different bodyno, change the key
409request_in_progressidempotency_errora retry while the first request is still being processedyes, in a few seconds
422model_input_invalidinvalid_request_errorthe parameters don't fit the modelno, fix input
429rate_limit_exceededrate_limit_errorrequest rate limit exceededyes, after Retry-After
429concurrency_limit_exceededrate_limit_errorconcurrent generation limit exceeded, if one is set; retry_after_seconds: 5 and Retry-After: 5yes, once a job finishes
500internal_errorapi_errorinternal erroryes, with growing pauses
503service_unavailableapi_errorservice temporarily unavailableyes, with growing pauses

AI Gateway errors (/v1/chat/completions and related endpoints) use the OpenAI format; their codes are listed on Chat Completions.

A live key requires an active subscription

Generation with a clipia_live_ key works only while the account has an active subscription on clipia.ai; a clipia_test_ key works without payment. Without a subscription, submit returns 402 subscription_required: buying a credit pack without a subscription does not unlock access, a plan is required. To check ahead: GET /v1/account shows the balance, and a cost estimate never returns 402 — it computes the price without checking payment.

Two responses outside the common format

The response to a body that cannot be parsed as JSON (400) and to an unknown route (404) is not wrapped in the error envelope; it looks like { "statusCode", "timestamp", "path", "message" }. Check the HTTP status before reading error.code.

Retries

What to retry

Retry 429, 500 and 503 with growing pauses: 1, 2, 4, 8 seconds, at most 5 attempts. For 429, wait as long as Retry-After says. Retry a generation submit with the same Idempotency-Key so the retry doesn't create a second job. Other 4xx errors, apart from 409 request_in_progress and 429, come back unchanged if you resend the same request.

No internal details

Error messages don't reveal internal infrastructure. For 500 and 503 the text is generic: "An internal error occurred. Please retry or contact support." and "Service temporarily unavailable. Please retry later."

A failed generation is not an HTTP error: the result request returns 200 with status: "FAILED" and an error object whose code comes from a separate dictionary (generation_failed, content_moderated, model_unavailable and others), and the credits go back to your balance. See Result.

On this page