[
  {
    "status": 400,
    "code": "invalid_multipart",
    "meaning": "The body is not readable multipart/form-data.",
    "action": "Send multipart fields audio, text and language; let your HTTP client set the boundary.",
    "finalized": false
  },
  {
    "status": 401,
    "code": "invalid_api_key",
    "meaning": "The key is missing, unknown or revoked.",
    "action": "Send Authorization: Bearer YOUR_KEY (or X-Api-Key). Create a key in the dashboard.",
    "finalized": false
  },
  {
    "status": 402,
    "code": "subscription_required",
    "meaning": "Free credits are used up and there is no active paid monthly plan.",
    "action": "Start or renew a plan in the dashboard. Existing credits are kept.",
    "finalized": false
  },
  {
    "status": 402,
    "code": "insufficient_credits",
    "meaning": "The plan balance does not cover this recording (1 credit per started 15 s). Free credits never cause this: a clip longer than the free credits left uses what is left.",
    "action": "Buy an extra credit pack or wait for the monthly renewal.",
    "finalized": false
  },
  {
    "status": 402,
    "code": "payment_balance_due",
    "meaning": "A refunded or disputed purchase left a balance to settle.",
    "action": "The next purchase settles it first.",
    "finalized": false
  },
  {
    "status": 408,
    "code": "upload_timeout",
    "meaning": "The upload took longer than 30 seconds. Nothing was charged.",
    "action": "Retry with the same key.",
    "finalized": false
  },
  {
    "status": 409,
    "code": "idempotency_conflict",
    "meaning": "This Idempotency-Key was used with different audio or fields.",
    "action": "Use a new key for a new attempt.",
    "finalized": false
  },
  {
    "status": 409,
    "code": "request_pending",
    "meaning": "The assessment for this key is still running.",
    "action": "Retry the same key shortly.",
    "finalized": false
  },
  {
    "status": 409,
    "code": "idempotency_expired",
    "meaning": "The stored result for this key is older than 24 hours.",
    "action": "Use a new key. An expired key never charges again.",
    "finalized": false
  },
  {
    "status": 413,
    "code": "upload_too_large",
    "meaning": "The upload is over 10 MB.",
    "action": "Send a shorter or compressed recording.",
    "finalized": false
  },
  {
    "status": 422,
    "code": "invalid_idempotency_key",
    "meaning": "The Idempotency-Key header is missing or malformed.",
    "action": "Send 8–128 letters, digits, dots, dashes, underscores or colons.",
    "finalized": false
  },
  {
    "status": 422,
    "code": "missing_audio",
    "meaning": "No file in the audio field.",
    "action": "Attach the recording as a file part named audio.",
    "finalized": false
  },
  {
    "status": 422,
    "code": "invalid_reference",
    "meaning": "No text or pinyin, or a field is too long.",
    "action": "Send text (up to 500 characters) or Mandarin pinyin (up to 1,000 characters).",
    "finalized": false
  },
  {
    "status": 422,
    "code": "invalid_task",
    "meaning": "task is not one of the accepted values.",
    "action": "Use general, connected_speech or isolated_word.",
    "finalized": false
  },
  {
    "status": 422,
    "code": "invalid_test_outcome",
    "meaning": "TonePerfect-Test-Outcome names an outcome a test key cannot rehearse.",
    "action": "Use success, unassessable, invalid_assessment, engine_unavailable, subscription_required, insufficient_credits, account_busy or rate_limit, or drop the header.",
    "finalized": false
  },
  {
    "status": 422,
    "code": "invalid_input",
    "meaning": "text, pinyin or language is not a string.",
    "action": "Send them as plain form fields.",
    "finalized": false
  },
  {
    "status": 422,
    "code": "unsupported_language",
    "meaning": "The locale is not available.",
    "action": "Choose an available locale from GET /v1/capabilities.",
    "finalized": false
  },
  {
    "status": 422,
    "code": "invalid_audio",
    "meaning": "The file could not be decoded, or is shorter than 0.15 s or longer than 30 s.",
    "action": "Send WAV, MP3, M4A, Ogg or WebM between 0.15 and 30 seconds.",
    "finalized": false
  },
  {
    "status": 422,
    "code": "invalid_assessment",
    "meaning": "The engine rejected this reference and recording, for example digits or Latin letters in a Mandarin reference, pinyin that does not match the characters, or text in the wrong script for the locale.",
    "action": "Check the reference text against the language. Not charged; a new attempt needs a new key.",
    "finalized": true
  },
  {
    "status": 429,
    "code": "rate_limit",
    "meaning": "More than 60 assessment requests in a minute for this account.",
    "action": "Slow down and retry the same key after a short delay.",
    "finalized": false
  },
  {
    "status": 429,
    "code": "account_busy",
    "meaning": "The account already has its concurrent-assessment limit running (2 by default; see limits in GET /v1/capabilities).",
    "action": "Wait for one to finish, then retry the same key.",
    "finalized": false
  },
  {
    "status": 429,
    "code": "free_capacity",
    "meaning": "Free credits have reached today’s shared daily limit. Nothing was charged.",
    "action": "Retry tomorrow with a new Idempotency-Key, or start a plan to use plan credits now.",
    "finalized": false
  },
  {
    "status": 503,
    "code": "gateway_busy",
    "meaning": "The upload gateway is at capacity. Nothing was charged.",
    "action": "Retry the same key after the Retry-After delay.",
    "finalized": false
  },
  {
    "status": 503,
    "code": "decoder_busy",
    "meaning": "The audio decoder is at capacity.",
    "action": "Retry the same key shortly.",
    "finalized": false
  },
  {
    "status": 503,
    "code": "audio_decoder_unavailable",
    "meaning": "Audio decoding is temporarily unavailable.",
    "action": "Retry the same key shortly.",
    "finalized": false
  },
  {
    "status": 503,
    "code": "engine_unavailable",
    "meaning": "The engine could not finish the assessment, or its queue was full (or, from GET /v1/capabilities, is unreachable).",
    "action": "If the body has an id and billing, it is finalized and not charged: retry with a new key after a short delay. Otherwise retry the same key.",
    "finalized": true
  },
  {
    "status": 503,
    "code": "request_interrupted",
    "meaning": "The request was interrupted before the engine finished. Not charged.",
    "action": "Retry with a new key.",
    "finalized": true
  }
]