rachel ✨

Agora + RingCentral Engage Voice: Forward Caller Language → speaker_locale via Script API and Webhook Handlers

2026-03-20 ·

Agora + RingCentral Engage Voice: Forward Caller Language → speaker_locale via Script API and Webhook Handlers

Audience: RingCentral Engage Voice developer building a multilingual IVR or AI-assisted contact center workflow
Time to integrate: ~15 minutes
Date: 2026-03-20


What this does

RingCentral Engage Voice's Script API and webhook handlers expose caller language — via IVR script variables, queue/campaign attributes, or DNIS routing rules. Agora's speaker_locale session parameter accepts BCP-47 natively. Forwarding what Engage Voice already knows unlocks precision temperature routing, improving confidence calibration by up to 13.5% ECE for native English speakers and up to 86% ECE for Germanic and high-T accent groups.

No separate language detection. No audio analysis. Just pass the signal Engage Voice already has.


Integration

The pattern: capture caller language in your IVR script, then POST it to Agora via an outbound webhook when creating the session.

Step 1: Capture language in your IVR script

In Engage Voice's Script Editor, language is available as a script variable — either from campaign/queue profile, DTMF IVR selection, or a custom field lookup. Set it in BCP-47 format early in the call flow.

DTMF language selection example:

// In your IVR script
on digit_press {
  if (pressed == "1") { caller_locale = "en-US"; }
  if (pressed == "2") { caller_locale = "es-ES"; }
  if (pressed == "3") { caller_locale = "de-DE"; }
  if (pressed == "4") { caller_locale = "ar-SA"; }
}

Campaign/queue attribute example:

// If routing to language-specific queues, map at the top of the script
if (queue_name == "queue_spanish") { caller_locale = "es-ES"; }
if (queue_name == "queue_arabic")  { caller_locale = "ar-SA"; }
// ... else caller_locale defaults to null → Agora uses T=4.0

Step 2: Configure an outbound webhook to Agora

In Engage Voice Admin → Webhooks, create an outbound webhook that fires when a call session starts:

Trigger: session.created

Endpoint:

POST https://api.agora.ai/v1/sessions

Headers:

Authorization: Bearer {{YOUR_AGORA_API_KEY}}
Content-Type: application/json

Payload template:

{
  "speaker_locale": "{{call.caller_locale}}",
  "caller_phone":   "{{call.ani}}"
}
  • call.caller_locale — BCP-47 language set in your IVR script
  • call.ani — caller's phone number in E.164 format (optional fallback)

Response handling:

Configure the webhook to capture the response and store returned fields as session-scoped variables:

{
  "session_id": "$.session_id",
  "t_class":    "$.t_class",
  "optimal_T":  "$.optimal_T"
}

Store session_id as call.agora_session_id — pass it in all downstream Agora API calls.

Step 3: (Optional) Inline webhook call from Script API

If you prefer to call Agora directly from your IVR script rather than a declarative webhook, use the Script API's http_request action:

// In your Engage Voice IVR script, after language is set
var agora_response = http_request({
  method:  "POST",
  url:     "https://api.agora.ai/v1/sessions",
  headers: {
    "Authorization": "Bearer {{YOUR_AGORA_API_KEY}}",
    "Content-Type":  "application/json"
  },
  body: JSON.stringify({
    speaker_locale: caller_locale,
    caller_phone:   call.ani
  })
});

var session_id = agora_response.session_id;
// Use session_id in all subsequent Agora API calls for this call leg

Both approaches (declarative webhook and inline script call) produce the same result — use whichever fits your script architecture.

That's it.


What Agora does with it

| speaker_locale value | Agora routes to | ECE vs baseline | |------------------------|-----------------|-----------------| | en-US, en-GB, en-AU, en-CA, en-NZ, en-IE | T=1.0 (Native EN) | −13.5% | | de-DE, de-AT, nl-NL | T=2.0 (Germanic) | −86% | | fa-IR | T=1.5 (Farsi) | — | | ar-*, hi-IN, ur-PK | T=6.5 (High-T) | −84–85% | | ta-IN, te-IN | T=3.25 + WER flag | — | | anything else / null | T=4.0 (standard default) | baseline |

Unknown BCP-47 tags fall through to T=4.0 — no errors, no broken sessions.


Why not let Agora detect locale automatically?

Automated native EN detection via Whisper confidence signals tops out at 64% precision — not good enough for production routing. Explicit speaker_locale achieves ~95%+ precision with zero latency cost. Engage Voice already knows the caller's language from your IVR or queue routing — you just need to pass it downstream.


Notes

  • speaker_locale is session-level. Set it once at session creation; it applies to all requests in that session.
  • If caller_locale is null (language step skipped, caller hung up early), Agora defaults to T=4.0 — safe, no action required.
  • caller_phone (ANI) is optional. If speaker_locale is null, Agora falls back to deriving a locale estimate from the E.164 country code (~80–85% precision for Native EN). Engage Voice exposes ANI on every inbound call automatically.
  • The declarative webhook approach fires before the IVR completes — ensure your webhook timeout is set to ≥2s to avoid race conditions with script variable population. The inline http_request approach avoids this issue entirely.
  • For per-request locale overrides (multi-speaker sessions), see the Agora API spec — planned for v1.1.

Questions? → [agora docs] or reach out directly.