Evom Labs

Developer platform

Error codes

REST, NDJSON and WebSocket can use different error shapes. Handle them according to the contract of the product you are calling.

On this page

Error shapes

Loly 3.5, REST

JSON
{
  "ok": false,
  "error": {
    "code": "QUOTA_EXCEEDED",
    "message": "Not enough quota remaining"
  }
}

Check ok first, then read error.code. Branch on code rather than message, because the wording may change.

Loli 2.0, REST

The STT surface has two error shapes. A failure raised by the public proxy uses the envelope; a failure returned by the STT service itself may have no ok field. A client has to accept both.

JSON
// Raised by the public proxy, before transcription starts
{ "ok": false, "error": { "code": "BAD_REQUEST", "message": "Error description" } }

// Raised by the STT service, no ok field
{ "error": { "code": "bad_request", "message": "Error description" } }

NDJSON and WebSocket

An error can also arrive inside the stream, after the HTTP response or the WebSocket handshake has already succeeded. Always check for an event with type error.

Loly 3.5

CodeHTTPMeaning
INVALID_API_KEY401, 403Key missing, wrong, inactive, revoked, expired, of the wrong type, or lacking the scope.
PERMISSION_DENIED403A valid account key has its required TTS, STT, audio-library or API-key usage switch turned off.
VOICE_ID_REQUIRED400An account-key TTS request omitted voice_id.
VOICE_NOT_ALLOWED403The requested voice does not exist, is outside the account-key scope, or conflicts with the voice key binding.
ACCOUNT_DISABLED403The account behind the enrollment key is disabled.
VOICE_NOT_FOUND404The voice bound to the voice key no longer exists.
VALIDATION_FAILED400A voice enrollment field is invalid. Read error.details[].
VOICE_LIMIT_REACHED403The account has reached the public enrollment ceiling.
RATE_LIMITED429Enrollments are arriving too fast. Read the Retry-After header.
ENROLLMENT_FAILED503Voice enrollment could not be completed.
BAD_REQUEST400A request field is missing or invalid.
TEXT_TOO_LONG400Batch text exceeds 5,000 characters.
INVALID_LANGUAGE400language is not auto, a catalog code, or a catalog name.
INVALID_FORMAT400format is not exactly wav or mp3.
KEY_CREDIT_EXCEEDED403The credential has exhausted its own lifetime character ceiling.
QUOTA_EXCEEDED403Not enough allowance remaining. Read GET /api/v1/usage.
VOICE_FEATURE_UNAVAILABLE503The selected clone voice's feature or reference audio could not be loaded; the model was not called.
BACKEND_ERROR4xx, 5xxThe generation backend refused the request or failed.
NOT_FOUND404The allowance record or the resource was not found.
INTERNAL_ERROR500An unclassified server fault.

Over WebSocket, an error arrives as a JSON event rather than as a REST envelope.

Loli 2.0

CodeHTTPMeaning
BAD_REQUEST, bad_request400Invalid multipart body, audio, language or duration.
INVALID_API_KEY, unauthorized401Key missing, wrong or revoked.
INVALID_API_KEY, FORBIDDEN403Key expired or lacking the scope.
KEY_CREDIT_EXCEEDED403The STT key exhausted its lifetime transcript-character ceiling.
QUOTA_EXCEEDED403The account has no STT quota left to start a request.
FILE_TOO_LARGE413The upload exceeds 100 MiB.
unsupported_audio_format415The container or encoding is not supported.
stt_upstream_error502The transcription engine failed.
SERVICE_NOT_CONFIGURED, STT_UNAVAILABLE, model_not_ready503The service is unconfigured, unreachable or not ready yet.
INTERNAL_ERROR, internal_error500An unclassified server fault.

Retrying

Retry 500, 502 and 503 only, with exponential backoff. A 4xx is caused by the request, so replaying it unchanged fails the same way.

The allowance is deducted up front

The allowance is deducted when the request is accepted, before synthesis runs. A request that fails inside the backend has already spent it, so blind retries consume the allowance faster than expected.