curl --request PUT \
--url https://api.inya.ai/platform/v1/agents/{botId} \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"greetingMessage": "Welcome! How may I assist you?",
"endMessage": "Thank you for calling. Have a great day!"
}
'{
"status": "success",
"requestId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"message": "Agent updated successfully",
"response": {
"botId": "fb79920229d144608ebf665a10e50275"
}
}{
"status": "failure",
"requestId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"message": "<string>"
}{
"status": "failure",
"requestId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"message": "<string>"
}{
"status": "failure",
"requestId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"message": "<string>"
}{
"status": "failure",
"requestId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"message": "<string>"
}Agents API
Update Agent
Update an existing agent’s configuration — all fields are optional
PUT
/
v1
/
agents
/
{botId}
curl --request PUT \
--url https://api.inya.ai/platform/v1/agents/{botId} \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"greetingMessage": "Welcome! How may I assist you?",
"endMessage": "Thank you for calling. Have a great day!"
}
'{
"status": "success",
"requestId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"message": "Agent updated successfully",
"response": {
"botId": "fb79920229d144608ebf665a10e50275"
}
}{
"status": "failure",
"requestId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"message": "<string>"
}{
"status": "failure",
"requestId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"message": "<string>"
}{
"status": "failure",
"requestId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"message": "<string>"
}{
"status": "failure",
"requestId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"message": "<string>"
}What it does: Update an existing voice agent’s configuration. All request body fields are optional — only the fields you include are modified. Unspecified fields retain their current values. This endpoint is the primary way to configure an agent’s ASR, LLM, TTS, language settings, advance settings, and integrations.
ASR Model Compatibility —
Each
When to use
Typical webhook flow:
Configure
Verify the saved configuration with Get Agent — both
403 Forbidden - Insufficient permissions (QA role)
404 Not Found - Agent not found or not accessible
409 Conflict - Agent name already taken
Required Permission
agents
Path Parameters
| Name | Type | Required | Description |
|---|---|---|---|
botId | string | Yes | Unique agent identifier. |
Top-Level Request Body Fields
| Field | Type | Description |
|---|---|---|
botName | string | New display name for the agent. |
description | string | Updated agent description. |
greetingMessage | string | Opening message spoken at the start of each call. |
endMessage | string | Closing message spoken before the call ends. |
systemPrompt | string | LLM system prompt. Supports Jinja2 template variables (e.g. {{ customer_name }}). |
hasDynamicGreeting | boolean | Enable fetching the greeting from an external API at call start. |
dynamicInitialMessageConfig | object | { hasHeaders, method, url, headers[{ id, key, value }] } — webhook config for dynamic greeting. |
botDetails | object | { language: string[] (max 3), region, timeZone, description } |
asrParams | object | { provider, model, language } — the selected model must support all configured languages. |
llmParams | object | { provider, model, temperature (0.0–1.0), maxTokens (1–4096) } |
ttsParams | object | { provider, voice, language, ttsRate (0.5–2.0), enableCaching } |
advanceSettings | object | ASR advance settings. See table below. |
languageSwitch | boolean | Enable automatic language switching mid-call. |
explicitLanguageSwitch | boolean | Use explicit language switch mode (agent asks the caller to confirm). |
languageSwitchMode | string | 'implicit' or 'explicit'. Controls how language switch is initiated. |
minWordsForLangSwitch | integer | Minimum words in the non-primary language before switching. Must be >= 1. Default: 2. |
callTransferConfig | object | { description, defaultTransferMessage, details[{ phoneNumber, countryCode, prompt, message }] } |
callTransferConfigStatus | boolean | Enable or disable call transfer functionality. |
preCall | object | { preCallVariableStatus, preCallParams: { primaryVariable, variables[] } } |
enableVoiceMailDetection | boolean | Enable the voicemail detection feature. |
voiceMailDetectionConfig | object | { enabled, maxDetectionRetries (>=1), maxVoicemailMessageWaitTime (>=1), voiceMailResponse, postDetectionActions[] } |
hasPostCallTrigger | boolean | Enable or disable the post-call webhook. See Post-call webhook. |
postCallTriggerAPIConfig | object | { hasHeaders, method ('GET' | 'POST'), url, headers[{ id, key, value }] } — called after every call ends. |
advanceSettings Fields
| Field | Type | Range / Notes |
|---|---|---|
barge | boolean | Enable or disable caller barge-in. |
initialMessageBarge | boolean | Allow the caller to interrupt the opening greeting. |
useDenoiser | boolean | Apply background noise filtering. |
suppressionLevel | integer | Noise suppression level: 20–100. |
enableItnForAsr | boolean | Apply Inverse Text Normalization to ASR output. |
maxSpeechDuration | number | Maximum utterance duration in seconds: 1–240. |
speechInitialSilenceTimeout | number | Silence threshold before ASR activates: 10–30s (streaming) or 10–60s (others). |
endSilenceTimeout | number | End-of-speech silence in milliseconds. Stored directly. |
speechSegmentationSilenceTimeout | number | Utterance segmentation silence gap: 0.1–5s. Streaming models only. |
minWordsForBargeIn | integer | Minimum words before a barge-in registers: 1–5. Streaming ASR only. |
minTimeToBarge | number | Minimum elapsed time before barge-in is accepted: 0.1–3s. Non-streaming ASR only. |
asrPreemptive | boolean | Enable Fast Streaming mode. Fast REST ASR models only. |
enableDtmf | boolean | Accept DTMF keypad input during the call. |
phraseConfig.phrase | string[] | Custom vocabulary hint phrases. Maximum 100 entries. Vocabulary-capable models only. |
phraseConfig.phraseWeight | number | Recognition bias weight for custom vocabulary: 0.0–2.0. |
Sending an
advanceSettings field that is not supported by the current ASR model returns HTTP 400. Use Get Transcriber Config to verify model compatibility before updating.ASR Model Compatibility — advanceSettings Reference
Each advanceSettings field is valid only for specific ASR model types. Sending an incompatible field returns HTTP 400.
| Setting | Valid For | Supported Models |
|---|---|---|
minWordsForBargeIn | Streaming only | gnani_asr, microsoft_streaming, elevenlabs_streaming, gladia_streaming, gemini-2.5-flash-native-audio-preview-09-2025 |
minTimeToBarge | Non-streaming (REST) only | microsoft_rest, elevenlabs_rest |
speechSegmentationSilenceTimeout | Streaming + select REST | microsoft_streaming, elevenlabs_streaming, microsoft_rest |
phraseConfig.phrase | Vocabulary-capable models only | microsoft_streaming, gnani_asr, elevenlabs_streaming, elevenlabs_rest |
asrPreemptive | Fast REST models only | elevenlabs_rest |
speechInitialSilenceTimeout (max 30s) | Streaming + select REST | microsoft_streaming, elevenlabs_streaming, microsoft_rest |
speechInitialSilenceTimeout (max 60s) | Other models | gnani_asr, gladia_streaming, gemini-2.5-flash-native-audio-preview-09-2025 |
barge, useDenoiser, enableDtmf, maxSpeechDuration | All models | Any |
Minimum working example
curl -X PUT "https://api.inya.ai/platform/v1/agents/fb79920229d144608ebf665a10e50275" \
-H "x-api-key: <your_api_key>" \
-H "Content-Type: application/json" \
-d '{
"greetingMessage": "Hello, how can I help you today?",
"endMessage": "Thank you for calling. Have a great day!"
}'
Additional examples
Full configuration update
curl -X PUT "https://api.inya.ai/platform/v1/agents/fb79920229d144608ebf665a10e50275" \
-H "x-api-key: <your_api_key>" \
-H "Content-Type: application/json" \
-d '{
"botName": "Support Agent v2",
"description": "Handles inbound support queries",
"greetingMessage": "Hello, how can I help you today?",
"endMessage": "Thank you. Have a great day!",
"systemPrompt": "You are a helpful support agent for {{company_name}}.",
"hasDynamicGreeting": true,
"dynamicInitialMessageConfig": {
"hasHeaders": true,
"method": "POST",
"url": "https://your-server.example.com/bot_initial_message",
"headers": [
{ "id": "1783576837993", "key": "Authorization", "value": "abc" }
]
},
"botDetails": {
"language": ["en-IN", "hi-IN"],
"region": "asia",
"timeZone": "Asia/Kolkata",
"description": "Handles support queries"
},
"asrParams": {
"provider": "gnani",
"model": "gnani_vachana_rest",
"language": "en-IN"
},
"llmParams": {
"provider": "gnani",
"model": "Pampa Go",
"temperature": 0.7,
"maxTokens": 400
},
"ttsParams": {
"provider": "gnani",
"voice": "Pranav",
"language": "en-IN",
"ttsRate": 1.2,
"enableCaching": true
},
"advanceSettings": {
"barge": true,
"initialMessageBarge": false,
"useDenoiser": true,
"suppressionLevel": 80,
"enableItnForAsr": false,
"maxSpeechDuration": 15,
"speechInitialSilenceTimeout": 10.0,
"endSilenceTimeout": 800,
"enableDtmf": false
},
"languageSwitch": true,
"languageSwitchMode": "explicit",
"minWordsForLangSwitch": 2,
"preCall": {
"preCallVariableStatus": true,
"preCallParams": {
"primaryVariable": "customer_name",
"variables": [
{ "variable": "customer_name", "sampleValue": "Alice", "description": "Customer name" },
{ "variable": "account_id", "sampleValue": "ACC123", "description": "Account ID" }
]
}
},
"enableVoiceMailDetection": true,
"voiceMailDetectionConfig": {
"enabled": true,
"maxDetectionRetries": 2,
"maxVoicemailMessageWaitTime": 3,
"voiceMailResponse": "Hi, we tried reaching you. Please call us back.",
"postDetectionActions": []
},
"callTransferConfig": {
"description": "Transfer to live agent",
"defaultTransferMessage": "Please hold, transferring you now.",
"details": [
{ "phoneNumber": "9876500000", "countryCode": "+91", "prompt": "Transfer", "message": "Hold on" }
]
},
"callTransferConfigStatus": false,
"hasPostCallTrigger": true,
"postCallTriggerAPIConfig": {
"hasHeaders": true,
"method": "POST",
"url": "https://your-server.example.com/call-completed",
"headers": [
{ "id": "1", "key": "Authorization", "value": "Bearer your-token" }
]
}
}'
phraseConfig is omitted above because it is not supported by gnani_vachana_rest. Use a vocabulary-capable ASR model (see the compatibility table) if you need custom phrase hints.Multilingual agent
SetbotDetails.language to an array of up to three language codes. Use Get Transcriber Config and Get TTS Config to pick models and voices that support every language in the list.
curl -X PUT "https://api.inya.ai/platform/v1/agents/fb79920229d144608ebf665a10e50275" \
-H "x-api-key: <your_api_key>" \
-H "Content-Type: application/json" \
-d '{
"botDetails": { "language": ["en-IN", "hi-IN"] },
"asrParams": {
"provider": "microsoft",
"model": "microsoft_streaming_multilingual",
"language": "en-IN"
},
"ttsParams": {
"provider": "gnani",
"voice": "Nalini",
"language": "en-IN"
},
"languageSwitch": true,
"languageSwitchMode": "explicit",
"minWordsForLangSwitch": 2
}'
Post-call webhook
Receive an HTTP callback at your URL when a call ends — instead of polling Get Conversation Logs on a schedule.When to use hasPostCallTrigger
| Approach | Set hasPostCallTrigger | Best for |
|---|---|---|
| Post-call webhook | true | CRM updates, payment reminders, SMS/email follow-ups, real-time dashboards |
| Poll Logs + Stats | false (default) | Historical backfills, bulk exports, ad-hoc QA review |
1. PUT /v1/agents/{botId} → set hasPostCallTrigger: true + your URL
2. Trigger Call → agent places the call
3. Call ends → platform POSTs payload to your URL
4. Your server → update CRM, send follow-up, store transcript
hasPostCallTrigger and postCallTriggerAPIConfig on the same Update Agent request.
Enable the webhook
curl -X PUT "https://api.inya.ai/platform/v1/agents/fb79920229d144608ebf665a10e50275" \
-H "x-api-key: <your_api_key>" \
-H "Content-Type: application/json" \
-d '{
"hasPostCallTrigger": true,
"postCallTriggerAPIConfig": {
"hasHeaders": true,
"method": "POST",
"url": "https://your-server.example.com/call-completed",
"headers": [
{ "id": "1", "key": "Authorization", "value": "Bearer your-token" }
]
}
}'
| Field | Description |
|---|---|
hasPostCallTrigger | Set true to enable. When a call ends, the platform POSTs call data to postCallTriggerAPIConfig.url. Set false to disable. |
postCallTriggerAPIConfig.method | GET or POST. Use POST when sending a JSON body. |
postCallTriggerAPIConfig.url | Your HTTPS endpoint. Must be reachable from the platform. |
postCallTriggerAPIConfig.headers | Optional auth or tracing headers sent with each callback. |
hasPostCallTrigger and postCallTriggerAPIConfig are returned on the agent object.
Expected webhook payload
When a call ends, the platformPOSTs a JSON body to your URL. Field names use snake_case (not the camelCase used by the Platform REST APIs). The payload includes call metadata, disposition extraction, the full transcript, and telephony CDR details.
Example payload from a verified post-call webhook:
{
"conversation_id": "1786446300918586082",
"bot_id": "fbec81f5c97c4a62b0103e87f53c0d56",
"bot_name": "Muthoot-sanity_outbound_-dev-c9dfdb3aedbc",
"bot_type": "voice_outbound",
"bot_language": "en-IN",
"bot_languages": ["en-IN"],
"environment": "development",
"call_type": "live",
"flow_id": "dev-c9dfdb3aedbc",
"organization_id": "f42bed74-4e0e-4dce-90ce-164982f021b9",
"user_id": "29be0f97-51c6-49aa-a515-e0433649e69d",
"user_name": "shyam.r@gnani.ai",
"phone": "+9109900186082",
"phone_number": 9900186082,
"user_context": {
"phone": "+9109900186082"
},
"callStatus": "ANSWERED",
"STAGE_CODE": "PTP",
"post_call_extraction": "NA",
"disposition_result": {
"DISPOSITION": "PTP",
"ptp_date": "2024-06-21",
"clbk_date": "no response",
"clbk_time": "no response",
"language_captured": "English"
},
"post_call_extraction_v2": {
"DISPOSITION": "PTP",
"ptp_date": "2024-06-21",
"clbk_date": "no response",
"clbk_time": "no response",
"language_captured": "English"
},
"transcript": [
{
"role": "assistant",
"content": "Hello, when will you pay your EMI amount? Please rate our services between 1 and 5.",
"timestamp": 1786446300.938049
},
{
"role": "user",
"content": "actually i don't have money right now can i pay later",
"timestamp": 1786446320.126243,
"total_results": { "en-IN": "actually i don't have money right now can i pay later" },
"detected_language": "english",
"user_interruption_flag": false
},
{
"role": "assistant",
"content": "Alright, That sounds fine. I will note that down. Thank you for your time. Have a good day.",
"timestamp": 1786446347.233017
}
],
"call_infra": {
"call_status": {
"callStatus": "ANSWERED",
"call_uid": "1786446300918586082",
"customerCRTId": "1786446300918586082",
"customerPhone": "9900186082",
"srcPhone": "+918035218872",
"dstPhone": "9900186082|dev-c9dfdb3aedbc;;Shyam R Pole",
"callType": "Outbound",
"ringingTime": "9",
"setupTime": "45",
"gnanivb_billing_duration": "45",
"callStartTime": "2026/08/11 16:35:01 +0000",
"callConnectedTime": "2026/08/11 16:35:09 +0000",
"callEndTime": "2026/08/11 16:35:55 +0000",
"rec_path": "dev-c9dfdb3aedbc/2026_08_11/dev-c9dfdb3aedbc-1786446300918586082-9900186082-2026_08_11-16_35_01",
"flow_id": "dev-c9dfdb3aedbc"
}
},
"rec_path": "dev-c9dfdb3aedbc/2026_08_11/dev-c9dfdb3aedbc-1786446300918586082-9900186082-2026_08_11-16_35_01",
"setupTime": "45",
"ringingTime": "9"
}
conversation_log mirrors transcript with the same turn-by-turn content. Both arrays are populated in live webhook deliveries — the example above omits duplicate entries for readability.Webhook fields arrive in snake_case. When your endpoint receives the post-call callback, read keys such as
conversation_id, bot_id, user_context, and disposition_result as snake_case — not the camelCase used by Platform REST APIs (conversationId, botId, userContext). Transcript user turns follow the same pattern: detected_language, total_results, user_interruption_flag. A few telephony fields (for example callStatus, setupTime) use camelCase — check the example payload above rather than assuming one convention everywhere.Payload field reference
| Field | Description |
|---|---|
conversation_id | Unique call identifier. Same value as call_uid and customerCRTId. Use for idempotency and to call Get Conversation Statistics or Get Conversation Audio. |
bot_id | Agent that handled the call. |
bot_name | Display name of the agent (includes environment suffix in development). |
bot_type | Agent direction — e.g. voice_outbound, voice_inbound. |
environment | Call environment: development, staging, or production. |
flow_id | Internal flow identifier for the agent deployment. |
user_id | Platform user identifier for the callee session. |
user_name | Session label or callee identifier (e.g. email or name from trigger data). |
phone / phone_number | Callee phone number in E.164 (phone) and numeric (phone_number) formats. |
user_context | Caller context passed at trigger time (e.g. { "phone": "+91..." }). |
callStatus | Telephony outcome at the top level — e.g. ANSWERED. Also nested under call_infra.call_status. |
STAGE_CODE | Short disposition code — see Disposition codes. |
disposition_result | Structured disposition extraction from the agent’s post-call prompt. Fields depend on your disposition configuration. |
post_call_extraction_v2 | Same structured extraction as disposition_result. Prefer this object when both are present. |
transcript | Full turn-by-turn conversation. User turns include detected_language, total_results, and user_interruption_flag. |
conversation_log | Duplicate of transcript with the same turn-by-turn content. |
call_infra.call_status | Telephony CDR record — connect/end timestamps, ringing and billing duration, source/destination numbers, and recording path. |
rec_path | Relative path to the call recording. Also available at call_infra.call_status.rec_path. |
setupTime / ringingTime | Billing and ringing duration in seconds (string). Duplicated from call_infra.call_status. |
Return HTTP
2xx from your endpoint quickly and process the payload asynchronously. Key your handler on conversation_id to stay idempotent — the same call may be delivered more than once.Pass
clientReferenceId on Trigger Call to link webhook payloads back to your CRM record. For a Platform-normalized view of the same call, use conversation_id with Get Conversation Statistics.Response
Success (200)
{
"status": "success",
"requestId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"message": "Agent updated successfully",
"response": { "botId": "fb79920229d144608ebf665a10e50275" }
}
Errors
400 Bad Request - Validation error{
"status": "failure",
"requestId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"message": "Selected ASR model does not support selected languages. Please check /platform/v1/agents/config/transcriber_config"
}
{
"status": "failure",
"requestId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"message": "QA role does not have permission to create/update agents"
}
{
"status": "failure",
"requestId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"message": "Agent not found or does not belong to your organization"
}
{
"status": "failure",
"requestId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"message": "An agent named 'Support Agent v2' already exists in your organization"
}
Always validate your ASR and TTS selections against the Agent Config API before updating. This ensures the selected provider/model combination supports all configured languages.
Save the
requestId from every response. You will need it if you contact Gnani support to trace a specific request.Authorizations
API key with 'agents' permission
Path Parameters
Unique identifier of the agent
Body
application/json
Supports Jinja2 template variables, e.g. {{ customer_name }}
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Available options:
implicit, explicit Required range:
x >= 1Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Was this page helpful?