Voice and SIP
Build a Package that answers phone calls on the installer's own number.
A phone-answering Package brings how the line behaves: the first message, the Agent that talks, the speech settings and the call routing. The installer brings everything that costs money or identifies them: speech-provider accounts, the carrier, the trunk and the number.
1. The Agent that takes the call
An ordinary Agent. Write its instructions for speech: short sentences, no markdown, confirm what you heard.
2. The voice configuration
name: After-Hours Line
sttProvider: soniox
sttConfig: { languageHints: [en] }
sttSlot: speech-in
ttsProvider: elevenlabs
ttsConfig: { model: eleven_flash_v2_5, stability: 0.5 }
ttsSlot: speech-out
callBehavior:
callFlow:
firstMessageMode: say
firstMessage: Thanks for calling. This is an automated assistant — how can I help?
recordCalls: false
consentMessage: null
agent: agents.intakeSay in the first message that the caller is talking to an automated assistant. It's the honest thing to do, and it's what the EU AI Act's transparency obligation asks of conversational systems.
sttConfig, ttsConfig and callBehavior accept any key, but a call reads only the ones listed for
each provider in
Voice and SIP definitions.
npx @elizon/cli validate warns about every other key.
3. The inbound routing template
sipTrunkSlot: phone-line
direction: inbound
inbound:
srtp: allow
sipHeaders: x_only
noiseCancellation: trueWhat each srtp and sipHeaders value does, and when to pick it, is on
Voice and SIP definitions.
sipTrunkSlot must name a declared sip-trunk Slot, or validate refuses it; use the one your
trigger names. The
headers sipHeaders lets through arrive on the call as sip.h.* participant attributes.
npx @elizon/cli example sip prints a complete phone-line project to start from.
4. The manifest
compatibility:
requiredCapabilities: [voice, sip]
voice:
ref: ./voice/after-hours-line.yaml
sip:
ref: ./sip/inbound.yaml
slots:
- id: speech-in
type: stt
required: true
allowedProviders: [soniox]
description: Your speech-to-text account.
- id: speech-out
type: tts
required: true
allowedProviders: [elevenlabs]
description: Your text-to-speech account.
- id: phone-line
type: sip-trunk
required: true
description: The trunk your after-hours number rings on, with the number routed to it.
triggers:
- id: after-hours-call
type: inbound-call
sipTrunkSlot: phone-line
routing:
ref: ./sip/inbound.yaml
- id: run-manually
type: manual
description: Replay a request without a call, to test after installing.The manual trigger matters. It lets the installer test the Package from Studio before any call
arrives.
Recording calls
If the Package records calls, set recordCalls: true and write the consentMessage callers hear
first. The installer must read it and confirm it suits where their calls are recorded, and the
wizard won't enable recording without a message.
What the installer does
- Voice step: choose their speech-to-text and text-to-speech providers and credentials (only
the providers in
allowedProvidersare offered). - SIP Inbound step: pick one of their inbound trunks that's ready, and the number the Package answers.
- Test inbound: call the number from any phone. The wizard confirms the call reached Elizon before activation. The line answers as it does today until the Package is activated.
- Activate: the routing template is applied to the chosen trunk. Nothing else about the trunk, the carrier account or other numbers changes.
Tell installers to arrange the trunk and number before they start. Carrier setup is the slow part; the install itself takes minutes.
See also Voice and SIP definitions and the Triage walkthrough.