Telephony Setup
Connect real phone numbers to your Arkenos voice agents using Twilio and LiveKit SIP. Arkenos auto-provisions most of the SIP infrastructure — you just need accounts and credentials.Telephony is optional. Browser-based voice testing via the Preview page works without any Twilio or SIP setup.
How It Works
- Inbound: Someone dials your Twilio number → Twilio routes via Elastic SIP Trunk to LiveKit → LiveKit dispatches the agent → agent looks up the called number and loads the right config
- Outbound: You click “Call” in the dashboard → backend creates a LiveKit room → LiveKit dials out through Twilio → agent joins the conversation
What’s Automated
When you buy or assign a number through the dashboard/API, Arkenos automatically:| Resource | Auto-Created |
|---|---|
| LiveKit Inbound SIP Trunk | Yes — “Arkenos Inbound” |
| LiveKit Dispatch Rule | Yes — routes to arkenos-agent |
| LiveKit Outbound SIP Trunk | Yes — “Arkenos Outbound” (on first outbound call) |
| Twilio Elastic SIP Trunk | Yes — “Arkenos Inbound” with LiveKit origination |
| Twilio ↔ Number association | Yes — links your number to the SIP trunk |
| Twilio termination credentials | Yes — for outbound calls via LiveKit |
Setup (3 Steps)
Step 1: Create Accounts
You need two accounts:- Twilio — free trial works (trial can only call verified numbers)
- LiveKit Cloud — free tier available
Step 2: Add API Keys via Dashboard
Open the Arkenos Dashboard → API Keys (under Build in the sidebar) and configure:- LiveKit — API Key, API Secret, Server URL (from LiveKit Cloud)
- Twilio — Account SID, Auth Token (from Twilio Console)
All keys are encrypted and stored in the database. No
.env files needed for provider credentials. The agent service auto-fetches keys from the backend on startup.Step 3: Buy a Number and Assign to an Agent
Start the backend, then use the dashboard or API: Option A: Via Dashboard- Open the Arkenos Dashboard → Agents → select your agent
- Go to the Phone tab → Search for available numbers
- Buy a number — it’s automatically provisioned and assigned
- Purchase the number on Twilio
- Create/reuse the LiveKit inbound SIP trunk
- Create/reuse the LiveKit dispatch rule
- Create/reuse the Twilio Elastic SIP trunk with LiveKit origination
- Associate the number with the trunk
Test It
Inbound Call
- Make sure the backend and agent services are running
- Call your Twilio number from any phone
- You should hear the agent’s greeting within a few seconds
- Check the agent terminal for logs:
Outbound Call
- Open the dashboard → select an agent with a phone number
- Click Make a Call → enter a destination number → Call
- The backend auto-provisions the outbound trunk on the first call
- Your phone should ring within a few seconds
Managing Numbers
Assign an Existing Twilio Number
If you already own a Twilio number and want to use it with Arkenos: Via Dashboard: Go to Agents → select agent → Phone tab → enter the number → Assign. Then click Test & Setup Pipeline to verify and provision the full SIP routing. Via API:Numbers bought through the dashboard are auto-provisioned. The Test & Setup Pipeline button is mainly needed when assigning numbers purchased directly from Twilio. If the Twilio SIP Trunk step shows a warning, clicking Test & Setup Pipeline again will attempt to resolve the Twilio SID automatically and complete the association.
Release a Number
Retry Failed Provisioning
If a number was bought but SIP provisioning failed:Troubleshooting
Call rings but agent doesn't pick up
Call rings but agent doesn't pick up
Most common cause: The agent service isn’t running.
- Start the agent:
cd agent && python agent.py dev - Verify in LiveKit Cloud → Telephony → Dispatch Rules that a rule exists with
arkenos-agent - Check the agent terminal for errors (missing API keys, etc.)
Call immediately disconnects
Call immediately disconnects
The agent is crashing on startup. Check the agent terminal for errors:
- Missing API keys: AssemblyAI, Google (Gemini), or Resemble AI key not configured at API Keys
- TTS credits exhausted: Check your Resemble AI balance at app.resemble.ai/hub/billing
- Key fetch failed: Check the agent terminal for “Could not fetch keys from backend” — ensure the backend is running
Inbound call doesn't ring / goes to voicemail
Inbound call doesn't ring / goes to voicemail
Twilio isn’t routing to LiveKit:
- Go to Twilio Console → Elastic SIP Trunking — verify “Arkenos Inbound” trunk exists
- Check the trunk has an Origination URI pointing to LiveKit (e.g.
sip:2w0eusjtqsa.sip.livekit.cloud) - Check your phone number is associated with the trunk (under Phone Numbers tab)
- Check Twilio → Calls Log to see if the call attempt was received
- If the trunk wasn’t auto-created, try the retry endpoint:
POST /api/telephony/numbers/provision
Outbound call initiates but phone doesn't ring
Outbound call initiates but phone doesn't ring
The outbound SIP trunk may not be configured correctly:
- Check Twilio Console → Elastic SIP Trunking — verify the trunk has a Termination SIP URI set
- Check LiveKit Cloud → Telephony → SIP Trunks — verify “Arkenos Outbound” exists with the correct Twilio termination address
- Check backend logs for
Failed to provision outbound trunkerrors - Twilio trial accounts: The destination number must be verified at Twilio Console → Verified Caller IDs
- Geographic permissions: Enable the destination country at Twilio Console → Voice → Geographic Permissions
Agent picks up but uses default config (wrong voice/STT)
Agent picks up but uses default config (wrong voice/STT)
For inbound calls: The phone number isn’t assigned to an agent in the database. Go to Dashboard → Agents → Phone tab → assign the number.For outbound calls: The room metadata might be missing the agent ID. Check that you’re using the latest backend code — the outbound call endpoint must include
metadata={"agentId": "..."} when creating the LiveKit room.- Check backend logs for
No agent found for phone +1234...messages - Verify the number is in E.164 format (e.g.
+14155551234)
Number purchase failed or provisioning incomplete
Number purchase failed or provisioning incomplete
If the buy succeeded but SIP setup failed:
- Check the backend logs for warning messages about provisioning
- Use the retry endpoint:
POST /api/telephony/numbers/provisionwith{"agent_id": "..."} - This re-runs the full provisioning chain without re-purchasing the number
Architecture Details
Auto-Provisioned Resources
All SIP resources are created with a reuse-first strategy — the system checks for existing resources by name before creating new ones:| Resource | Name | Purpose |
|---|---|---|
| LiveKit Inbound Trunk | ”Arkenos Inbound” | Receives SIP calls from Twilio |
| LiveKit Dispatch Rule | ”Arkenos Dispatch” | Routes calls to arkenos-agent worker |
| LiveKit Outbound Trunk | ”Arkenos Outbound” | Sends SIP calls to Twilio |
| Twilio Elastic SIP Trunk | ”Arkenos Inbound” | Routes calls between Twilio and LiveKit |
| Twilio Credential List | ”Arkenos LiveKit” | Authenticates LiveKit → Twilio for outbound |
How the SIP Domain is Resolved
The SIP domain is auto-derived from your LiveKit Server URL:twilio_sip_domain via the settings API.
Provisioning Code
The provisioning logic lives inbackend/app/services/telephony_provisioning.py. Key functions:
ensure_inbound_trunk()— Creates/reuses LiveKit inbound trunkensure_dispatch_rule()— Creates/reuses dispatch ruleensure_outbound_trunk()— Creates/reuses outbound trunk + Twilio credentialsensure_twilio_elastic_trunk()— Creates/reuses Twilio Elastic SIP Trunk