Text & Extraction API
POST /chat/completions — an OpenAI-compatible text endpoint, built as the side channel for voice agents: everything that reasons about a conversation instead of speaking in it. Structured extraction, outcome classification, post-call QA scoring, voicemail detection, idle re-prompts, chat-mode testing — one endpoint powers them all, with native Hindi, Hinglish and code-switched comprehension.
Point any OpenAI SDK at base URL https://platform.oogam.ai/v1 with your existing sk-setu-… key. A Naad (voice) key can call naad-text-v1 directly — no extra product signup.
Structured extraction
Set response_format to {"type": "json_object"} and the reply's content is guaranteed parseable JSON — the platform validates it server-side (and retries the model once if needed) before answering, so JSON.parse on the content never throws. Combined with temperature: 0 the output is deterministic: the same transcript yields the same record.
curl https://platform.oogam.ai/v1/chat/completions \
-H "Authorization: Bearer $OOGAM_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "naad-text-v1",
"temperature": 0,
"response_format": {"type": "json_object"},
"messages": [
{"role": "system",
"content": "Return JSON with keys date (YYYY-MM-DD) and time (HH:MM, 24h)."},
{"role": "user",
"content": "25 अगस्त 2026 को शाम 5 बजे का appointment book कर दो"}
]
}'Tip: state dates explicitly (or pass today's date in your system prompt and post-process relative words like कल/परसों yourself) — explicit anchors extract deterministically.
Response — standard shape, with real token usage for cost attribution:
{
"id": "chatcmpl-1e97a0ee22d04527b805315c",
"object": "chat.completion",
"created": 1755763200,
"model": "naad-text-v1",
"choices": [{
"index": 0,
"message": {
"role": "assistant",
"content": "{\"date\": \"2026-08-25\", \"time\": \"17:00\"}"
},
"finish_reason": "stop"
}],
"usage": {"prompt_tokens": 81, "completion_tokens": 29, "total_tokens": 110}
}Request parameters
| Field | Type | Required | Notes |
|---|---|---|---|
model | string | no | Optional. naad-text-v1 (recommended for voice-agent work), or sutra-v2 / sutra-v2-pro with a Sutra-enabled key. Omit to use the default text model. See GET /models. |
messages | array | yes | Standard role/content messages. String content only; 1–200 messages, ≤100,000 characters total. Request body ≤256 KB. |
temperature | number | no | Between 0 and 2. Forwarded verbatim — 0 is deterministic. Out of range → 400 invalid_temperature. |
max_tokens | integer | no | Positive integer (≥1) capping the completion length. Invalid → 400 invalid_max_tokens. |
response_format | object | no | {"type":"json_object"} for enforced JSON (an object, never a scalar or array), or {"type":"text"} (default). |
stream | boolean | no | true streams Server-Sent Events — see below. |
tools / tool_choice | — | no | Not supported yet — rejected with a clear 400 tools_not_supported, never silently ignored. |
Response (non-streaming): the object shown above — id, choices[0].message.content, and a usage block with real token counts. With json_object, content is a JSON object string; parse it directly.
Streaming
With stream: true the response is text/event-stream: a first chunk carrying delta.role, then content chunks, a final chunk with finish_reason: "stop", and the literal data: [DONE] sentinel. Each event is a chat.completion.chunk. Note the stream does not include a usage block — read token usage from a non-streaming call, or from your dashboard. Most voice-agent tasks (extraction, classification) are batch, so streaming is optional.
data: {"id":"chatcmpl-…","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"role":"assistant"},"finish_reason":null}]}
data: {"id":"chatcmpl-…","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"content":"नम"},"finish_reason":null}]}
data: {"id":"chatcmpl-…","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"content":"स्ते"},"finish_reason":null}]}
data: {"id":"chatcmpl-…","object":"chat.completion.chunk","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}
data: [DONE]Endpoint errors
| Status | Code | Meaning |
|---|---|---|
| 400 | tools_not_supported | Remove tools/tool_choice; express the task as instructions + json_object. |
| 400 | invalid_response_format | Only text and json_object are supported. |
| 400 | invalid_temperature / invalid_max_tokens | Out-of-range sampling parameters. |
| 400 | model_not_text | The model id belongs to another modality. |
| 400 | missing_messages / too_many_messages / invalid_message | Empty, over 200, or non-string content. |
| 413 | payload_too_large / prompt_too_large | Body over 256 KB, or messages over 100k characters. |
| 502 | json_generation_failed | The model could not produce valid JSON even after a retry. Retryable. |
| 503 | model_not_configured | The text model is not activated on this deployment. Retryable after Retry-After. |
Everything else (auth, rate limits, wallet) uses the shared error contract.
Embeddings
POST /embeddings — OpenAI-compatible, model naad-embed-v1, for building retrieval over Indian-language content without shipping documents offshore.
| Field | Type | Required | Notes |
|---|---|---|---|
input | string or array | yes | One string, or an array of up to 96 non-empty strings, each ≤16,000 characters. Body ≤4 MB. |
model | string | no | Defaults to naad-embed-v1. |
curl https://platform.oogam.ai/v1/embeddings \
-H "Authorization: Bearer $OOGAM_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "naad-embed-v1",
"input": ["ऑर्डर कहाँ है?", "मुझे रिफंड चाहिए"]
}'Response: data holds one embedding per input, in order, each with its index. The vector dimension is fixed per model version and published at activation — it is a stability contract, so declare it once in your vector(N) column.
{
"object": "list",
"data": [
{ "object": "embedding", "index": 0, "embedding": [0.013, -0.221, …] },
{ "object": "embedding", "index": 1, "embedding": [-0.047, 0.164, …] }
],
"model": "naad-embed-v1",
"usage": { "prompt_tokens": 12, "total_tokens": 12 }
}Status: activating soon. Until an embeddings provider is enabled on the deployment, the endpoint answers 503 model_not_configured (JSON, with a Retry-After header) — never a mock vector, which would silently corrupt your index. Over-limit batches return 400 batch_too_large; over-long inputs 400 input_too_long; empty input 400 missing_input.
Latency & determinism
- Typical extraction over a few-hundred-token transcript: ~1 second.
temperature: 0+ same input → same output, run after run.usagereports the model's own token counts — bill and attribute per call.