SIP integrations¶
Status: Current | Last reviewed: 2026-08-11
How each carrier and contact-center integration reaches ai-orchestrator. They share the same downstream pipeline; what differs is the protocol they speak upstream.
The integrations¶
| Integration | Mode | Service | Protocol upstream | Downstream |
|---|---|---|---|---|
| Genesys Cloud (BYOC) | SIP carrier + AudioHook | genesys-connector-go |
SIP via kamailio + AudioHook WebSocket | media-proxy → ai-orchestrator |
| Genesys Cloud (server-side WebRTC) | WebRTC agent | genesys-agent-go |
WebRTC over WSS to Genesys | direct gRPC to ai-orchestrator |
| Webex Contact Center (BYOVA) | Custom voice agent | webex-connector-go |
Webex BYOVA WebSocket | media-proxy → ai-orchestrator |
| Five9 | VoiceStream | five9-voicestream-connector-go |
Five9 WebSocket | media-proxy → ai-orchestrator |
| Amazon Connect | KVS + emulator WebRTC | connect-kvs-connector + ai-manager |
Reads Kinesis Video Stream; starts web contacts for emulator tests | gRPC to ai-orchestrator / browser Chime audio |
| Salesforce SCV (BYOT) | Telephony partner | connect-scv-translator |
SCV API (HTTP + Socket.IO) | dispatches to Genesys / Connect / demo |
What they have in common¶
All produce frames that look like:
{
conversation_id: <uuid>,
audio: <PCM, sample rate, channels>,
metadata: { caller_number, called_number, attributes... }
}
ai-orchestrator does not care which integration produced the frame. It looks up the agent for called_number → tenant → agent, builds a pipeline, and runs it.
They also share the CCaaS allow-list gate: every inbound call that carries CCaaS identification (Genesys org id, Amazon Connect source ARN) is validated by ari-controller against ccaas_pipeline_integrations — the agent must be explicitly enabled for the calling integration or the call is rejected (default-deny). Operators control this per agent from the publish dialog's CCaaS Availability section in ai-manager. See ari-controller.
What is different per integration¶
Genesys (BYOC)¶
SIP trunk into kamailio (5060/5061). Calls land in asterisk via PJSIP, hand off to ari-controller, bridge to media-proxy. AudioHook is a parallel realtime audio stream Genesys sends over WebSocket — used for transcription and analytics by some customers, terminated by genesys-connector-go for orchestration.
City dev environments require per-city TLS certs and a trunk ACL allowlisting the city's NAT egress IP. See city-dev-environments.md.
Genesys (server-side WebRTC)¶
A pure-Go service (genesys-agent-go) logs into Genesys as a WebRTC agent. It receives audio over WebRTC and forwards to ai-orchestrator. No SIP stack involved on our side. Used for outbound campaigns and WebRTC-only Genesys orgs.
UI for triggering: hidden at /agent-simulation in ai-manager.
Webex BYOVA¶
Webex Contact Center treats us as a "virtual agent". Audio arrives over their BYOVA WebSocket protocol. The Go connector terminates the protocol and forwards.
A separate service, webex-app-manager, handles OAuth lifecycle, datasource registration, and webhook delivery for the management plane.
Five9 VoiceStream¶
Five9 emits real-time audio over their VoiceStream WebSocket. The Go connector terminates and forwards.
Amazon Connect (KVS)¶
Connect publishes call audio to Kinesis Video Stream. connect-kvs-connector (Java) reads KVS, decodes, and forwards stereo PCM to ai-orchestrator.
For session metadata (DNIS, ANI, contact attributes), connect-session-start-lambda bridges Connect's Contact Flow to the connector.
The standalone ai-manager /emulator also supports an Amazon Connect WebRTC dial mode. That path does not dial PSTN or SIP. Instead, ai-manager lists contact flows for the selected Connect instance, calls StartWebRTCContact, and the browser joins the returned Chime meeting. Amazon Connect treats the session as an inbound web contact that starts the selected flow.
Configuration lives on an Amazon-sourced integration with the telephony capability:
source_arnis the Amazon Connect Instance ARN. Runtime helpers parse both the Connect instance ID and region from it.- Optional
default_contact_flow_idto preselect a flow in the emulator. - Optional
outbound_contact_flow_id,outbound_source_phone_number,outbound_queue_idfor workflow-originated outbound calls (below). - Optional
voice_connector_id— the Chime Voice Connector id, matched against theX-VoiceConnector-IDheader when an arriving leg carries no Connect ARN. - Optional encrypted
access_key_id,secret_access_key, andsession_token. If omitted, the AWS SDK default credential chain is used. All three aresecret: true, so each shows Leave blank to keep unchanged on edit; every reader resolves secrets first and falls back toconfig, so a row still holding a plaintextaccess_key_idkeeps working.session_tokenis only for temporary STS credentials — it is read by every service that signs an AWS request, so a stale value breaks all of them at once when it expires. - In ai-manager, Discover AWS resources fills every discoverable field from the current credentials: Connect instances (
source_arn), then — once an instance is resolved — contact flows (bothdefault_contact_flow_idandoutbound_contact_flow_id),STANDARDqueues (outbound_queue_id), and claimed phone numbers (outbound_source_phone_number, stored as the E.164 number, not the phone-number id). Chime Voice Connectors (voice_connector_id) come from a separate hand-signedGET voice-chime.<region>.amazonaws.com/voice-connectors— the Chime SDK Voice signing name ischime, notchime-sdk-voice, and only some regions host that endpoint, so an integration elsewhere gets a warning naming the region instead of an opaque DNS failure. Each list is a separate IAM action and runs in its owntry, so one missing permission empties one dropdown rather than all of them. Every field stays typable — the manual input under each dropdown always shows the stored value.
Outbound is the other direction, and Connect owns it. Connect exposes no trunk we can originate on, so a workflow's Start Conversation node does not call ari-controller for a Connect integration — it calls StartOutboundVoiceContact, and the contact flow transfers the answered leg back to us over the Chime Voice Connector, where it arrives as an ordinary inbound Connect call subject to the allow-list gate above. Only Genesys BYOC dials through our own SIP edge.
The emulator sends participant display name and contact attributes such as name, ani, caller_id_number, caller_id_name, and any custom keys entered by the tester. The backend validates attribute keys and payload size before forwarding them to Connect.
Salesforce SCV BYOT¶
Salesforce Service Cloud Voice (BYOT) treats us as a telephony partner. The SCV partner package is at sfdc/trueserve-scv/.
connect-scv-translator is the backend. Its dispatch layer routes to:
- Genesys (for customers with Genesys carriers).
- Amazon Connect (for customers with Connect).
- Demo mode (in-house simulation for testing).
The dispatch is server-side based on TELEPHONY_PROVIDER env var; the SCV LWC sees a single API.
CES (Cloud Engagement Suite) session routing¶
Some integrations layer Google's Cloud Engagement Suite on top. CES gives a session ID per conversation. We map CES's Mcp-Session-Id to our internal conv_id via Redis (mcp:el_mapping:<ces_session>), TTL 1h.
There are two ways to bind tenant variables:
- REST
runSessioninputs[].variables— works once per session. Used at session start. - OpenAPI tools with
$context.session_idsubstitution — works every call. Used for runtime tool invocations.
See agent memory ces-session-variable-binding and ces-openapi-session-routing for the gotchas.
SIP trace logging¶
When a call fails, capture SIP traces:
docker exec -it tsf-local-kamailio kamcmd tm.t_dump_uac
docker exec -it tsf-local-asterisk asterisk -rx "pjsip set logger on"
For cluster deploys, see troubleshooting voice.