Introducing Naad v1

Developers

Developer hubDocumentationQuickstartModelsAudio & Voice APISpeech-to-SpeechAuthenticationError referenceSolutions

Resources

BlogSystem statusDesktop appsPricingSign inSign up

Error reference

Every error, on every /v1 path, is JSON in one envelope — including 404 for unknown paths and 405 for wrong methods, so response.json() never breaks on an Oogam error. Program against error.code — codes are stable; the human-readable message may improve over time.

Error envelope
{
  "error": {
    "message": "'input' exceeds the 5,000 character limit per request.",
    "type": "invalid_request_error",
    "code": "input_too_long"
  }
}

Codes by status

StatusCodeWhat happenedRetryable?
400invalid_jsonBody was not valid JSON.No — fix the request.
400missing_input / input_too_longRequired input absent or over its limit (TTS 5,000 chars; embeddings 16,000/input).No — chunk the input.
400missing_language / invalid_languageLanguage missing or unknown — the models never auto-detect.No — send a valid code (list).
400invalid_voiceVoice id not in the catalogue.No — pick from GET /voices.
400missing_fileMultipart form had no file part.No.
400tools_not_supportedtools/tool_choice sent to /chat/completions.No — remove them; use response_format.
400invalid_response_format / model_not_textUnsupported response_format.type, or a non-text model on the text endpoint.No.
400invalid_temperature / invalid_max_tokensSampling parameter out of range (temperature 0–2, max_tokens ≥1).No.
400missing_messages / too_many_messages / invalid_messageChat messages empty, over 200, or non-string content.No.
400invalid_url / invalid_requestKB URL not http(s), or KB name not 1–120 chars.No.
400batch_too_largeEmbeddings batch over 96 inputs.No — split the batch.
400kb_limit_reached / kb_document_limit_reached / unsupported_file_type / file_too_largeKnowledge-base limits — see Knowledge Bases.No.
400missing_inputKB document upload had no file, url, or text.No.
401missing_api_keyNo Authorization: Bearer header.No — add the header.
401invalid_api_key / revoked_api_key / expired_api_keyThe key is wrong, revoked, or past its expiry.No — use a current key.
402insufficient_creditsThe project wallet is empty.After top-up.
402spend_limit_exceededThe project's monthly cap is reached.After raising the cap.
403insufficient_permissionsThe key lacks this product (type permission_error).No — enable the product on the key.
403api_not_availableThis product's API is not public yet.No — contact us for early access.
403project_archived / account_suspended / org_requiredThe project/account is inactive, or the key has no workspace (KB).No.
404model_not_foundUnknown model id — see GET /models.No.
404not_foundUnknown path, job id, kb_id or doc_id.No.
405method_not_allowedWrong HTTP method — the Allow header lists valid ones.No.
413payload_too_large / prompt_too_largeUpload or body over the cap (STT 200 MB, isolate 150 MB, others 25 MB; JSON bodies 256 KB–4 MB; chat messages 100k chars).No — compress or split.
429rate_limit_exceededToo many requests this minute for this key.Yes — wait Retry-After seconds.
429too_many_sessionsConcurrent realtime session cap reached (see limits below).Yes — after a session ends.
WS eventcontext_too_largeRealtime set_context.system over 8,000 characters. Carries active_context: "previous" (old prompt still live) or "none".No — shorten the prompt and resend.
WS eventno_active_contextThe session's only set_context was rejected, so there is no system prompt; start_utterance, say and audio are refused rather than running an uninstructed agent.No — send a valid set_context, then start the call.
WS eventsay_too_longRealtime say.text over 500 characters per chunk.No — split into sentences.
WS eventinvalid_voice (realtime)Voice id is not f1f4/m1m4 or a v_… clone id.No — pick from GET /voices.
WS eventkb_not_foundThe kb_id in set_context does not exist for your account.No — check the id, or create the KB.
WS eventkb_emptyThe knowledge base has no documents in ready status.After a document finishes ingesting.
WS eventkb_not_availableThe session has no workspace (e.g. a demo token), so a KB cannot be attached.No — connect with an API key.
WS eventkb_no_roomThe system prompt leaves no budget for knowledge-base content.No — shorten the prompt.
WS eventlanguage_at_capacityPer-language concurrent-call capacity reached.Yes — back off, retry shortly.
502upstream_errorThe model failed or was unreachable.Yes — backoff below; report if persistent.
502json_generation_failedThe model could not produce valid JSON after a retry.Yes — simplify the instruction or retry.
503model_not_configuredThis model has no active provider on the deployment.Yes — after Retry-After; contact support if persistent.

Rate limits & session caps

LimitDefaultOn exceed
Requests per key60/minute (adjustable per key in the dashboard)429 rate_limit_exceeded + Retry-After
Concurrent realtime sessions per API key5429 too_many_sessions on upgrade
Concurrent Live talk calls per user2429 too_many_sessions on upgrade
Max realtime session length120 minutesClose 1000 "Session length limit reached"

Higher limits are available per plan — contact us.

HTTP
# 429 and 503 responses include how long to wait:
HTTP/1.1 429 Too Many Requests
Retry-After: 60

Async STT job failures

Polling GET /audio/transcriptions-status/{id} can resolve to 200 {"status":"failed","error":"…"}. Failed jobs are never billed. If the same file fails repeatedly, re-encode it as WAV and retry — and tell us; deterministic failures on valid files are model bugs we chase.

Realtime WebSocket closes

Close codeMeaningRetryable?
1000 / 1001Normal close / server restarting.Yes — reconnect.
1011Transient engine trouble ("Realtime service unavailable / slow — try again").Yes — reconnect with backoff (below). These recover within a minute in practice.
4402Wallet ran out mid-call.After top-up.
HTTP 401 on upgradeBad or missing credentials — see realtime auth.No.
HTTP 429 on upgradetoo_many_sessions or connect throttle; Retry-After is included.Yes — after the header's delay.

Session state does not survive a reconnect. The engine keeps no conversation memory across connections — after any close, reconnect and replay your setup (set_lang set_voiceset_context → optionally a resume line via say). For a caller on the line, keep the telephony leg open, play a brief hold prompt, and reconnect the engine leg behind it.

Backoff
// Recommended retry loop for retryable codes (1011, 502, 429, 503):
for (const delayMs of [1000, 2000, 4000]) {
  const ok = await tryOnce();
  if (ok) break;
  await sleep(delayMs);
}