Skip to content

Guides

Bring your own agent

Want to connect your own voice platform - ElevenLabs Conversational AI on your own workspace, Vapi, Retell, or even a plain Asterisk/FreeSWITCH IVR - to a volai number instead of the built-in agent? This page covers both directions: inbound and outbound calls. For outbound, you also skip the agent surcharge of 2.50 CZK/min (~EUR 0.10) - you run (and pay for) the agent yourself on your own platform.

Quick overview

Inbound calls are set up by routing the number to your platform's SIP address - no new mechanics. Outbound calls travel through a short-lived relay connection, because the platform itself can't keep a line permanently registered as a SIP client.

You'll need: a volai number, an API key (vk_...) and an account with your platform (ElevenLabs, Vapi, your own PBX...).

1Own agent vs. the built-in one

Both paths run on the same number and the same credit - they only differ in WHO runs the conversation logic and how much that costs on top:

CriterionBuilt-in agentYour own agent
Who drives the conversationWe do - one systemPrompt, our voice and our ElevenLabs workspace.You do - any platform, your own prompt, your own voice, your own tools.
SetupOne POST /v1/agents call.The number's SIP credentials + your platform's configuration (this page).
Call price0.92 CZK/min (~EUR 0.04) outbound, 0.50 CZK/min (~EUR 0.02) inboundsame - 0.92 CZK/min (~EUR 0.04) outbound, 0.50 CZK/min (~EUR 0.02) inbound
Agent surcharge+ 2.50 CZK/min (~EUR 0.10)none (0 CZK) - you only pay for call minutes
Transcript, summary, voicemail detectionYes, automatically.No - your own platform handles it (or doesn't).

You skip the agent surcharge, but you don't get anything extra from us for free either - you pay for your own platform (ElevenLabs, Vapi...) directly, at its own rates. We only bill call minutes on the volai line, same as with a SIP client or the built-in agent. Rates exclude VAT, like the whole price list.

2Inbound calls to your own agent

No new mechanics - just the existing mode: "sip" routing (same as for your own softphone, see SIP) with your platform's sipUri address. For an ElevenLabs SIP-trunk number registered on YOUR OWN workspace, that's one with the same number as your volai line:

bash
curl -X PATCH "https://volai.cz/v1/numbers/+420601234567" \
  -H "Authorization: Bearer vk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"routing": {"mode": "sip", "sipUri": "sip:+420601234567@sip.rtc.elevenlabs.io"}}'

And on your ElevenLabs account (Settings → Phone Numbers → Import → SIP trunk) you register this number with inbound_trunk_config:

json
{
  "provider": "sip_trunk",
  "phone_number": "+420601234567",
  "label": "My own agent",
  "inbound_trunk_config": {
    "allowed_addresses": ["81.31.45.0/24"],
    "media_encryption": "allowed"
  }
}

allowed_addresses above is our signalling range (81.31.45.0/24) - safer than the universal 0.0.0.0/0, which lets an INVITE in from anywhere. Both let the call through, but for an import without credentials the allowlist is the ONLY check - so use the range, not 0.0.0.0/0.

Using a different platform than ElevenLabs? Same principle - find out the SIP address it expects calls for your number on, and put that into sipUri. For Vapi, the same range goes into the BYO trunk's gateways.

For Vapi, the routing address is sip:<E164>@<credentialId>.sip.vapi.ai - find <credentialId> on your BYO SIP trunk in Vapi; the bare sip.vapi.ai belongs to native Vapi numbers and doesn't work for a number from us.

3Outbound calls from your own agent (relay)

This is the reverse direction - your platform dials out on its own. Most voice AI platforms (ElevenLabs included) can't permanently register a phone line as a SIP client - they only send a single authenticated call using your line's credentials. The phone network won't let such a call straight through to the destination number, so you route it through a short-lived relay connection instead:

Why relay, not a direct call

Dialing the destination number directly through the trunk doesn't work either way: to a number outside our network, the call never comes into being at all (the platform reports failure, with no trace of it anywhere), and to another volai number inside our network it only connects INTERNALLY as an anonymous call - it never actually leaves our network, even though it looks connected. The relay is the only way to actually get a call out.

1. Point your platform at your line

Fetch your line's SIP credentials:

bash
curl "https://volai.cz/v1/numbers/+420601234567/sip" \
  -H "Authorization: Bearer vk_YOUR_KEY"
json
{
  "server": "sip.volai.cz",
  "username": "123456",
  "password": "a1b2c3d4e5f6",
  "outboundTrunkAddress": "sip.volai.cz",
  "port": 5060,
  "transport": "tcp",
  "inboundSignallingCidrs": ["81.31.45.0/24"]
}

The response returns server (for a softphone's REGISTER, see SIP) and outboundTrunkAddress SEPARATELY - they are not interchangeable.

And set outboundTrunkAddress - NOT server - as your platform's outbound trunk. For ElevenLabs, that's the outbound_trunk_config of the phone number in question (Settings → Phone Numbers → your number → Outbound calling), in exactly this shape:

json
{
  "outbound_trunk_config": {
    "address": "sip.volai.cz",
    "transport": "tcp",
    "media_encryption": "allowed",
    "credentials": {
      "username": "123456",
      "password": "a1b2c3d4e5f6"
    }
  }
}

Use exactly outboundTrunkAddress

The outbound trunk address must be exactly the value of outboundTrunkAddress from the response - whether or not it matches server. A different address means the call is not routed on the network and the platform reports it as 1011 sip request timed out - nothing is left in the call history.

2. Create a relay connection

Right before the call (the connection has a short lifetime, see the limits below), call:

bash
curl -X POST https://volai.cz/v1/relay \
  -H "Authorization: Bearer vk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"to": "+420777123456", "from": "+420601234567"}'
json
{
  "id": "rl_4f2a91cd",
  "sipName": "volai_relay_2",
  "sipUri": "sip:volai_relay_2@sip.volai.cz",
  "expiresAt": 1756111760000,
  "callId": "c_9d4e2b7f"
}

You give US the destination number in to - the platform never sees it, it only gets the bare sipName from the response.

3. Tell your platform to call the sipName

The bare name, not the full SIP URI

ElevenLabs to_number rejects a full SIP URI with "SipCallTo should be a phone number or SIP user, not a full SIP URI" - that's why the response above returns sipName (the bare volai_relay_2) and sipUri (the full sip:volai_relay_2@sip.volai.cz) SEPARATELY. Only the former belongs in to_number - never the full URI.

For ElevenLabs, this means calling /v1/convai/sip-trunk/outbound-call with to_number set directly to the sipName:

json
{
  "agent_id": "agent_...",
  "agent_phone_number_id": "phnum_...",
  "to_number": "volai_relay_2"
}

agent_id is found on your agent in ElevenLabs, agent_phone_number_id is the phone_number_id of the imported number - the import response returns it, or you can read it off the Phone numbers list.

Using your own SIP client or PBX instead of ElevenLabs? Dial the full sipUri directly, like an ordinary SIP call - that restriction only applies to platforms that want a bare name without the sip: prefix.

4. What happens next

The phone network accepts the call under the name volai_relay_2, transfers it to your to and sets the visible caller ID to your from - the callee sees your volai line on their display, not the relay slot's internal name (only if the number has its own relay names - see Billing below, otherwise the callee sees volai's demo number). Once the call ends, the lease is released and the minutes are billed exactly like a regular outbound call - 0.92 CZK/min (~EUR 0.04), no agent surcharge.

The response confirming the call comes back only after the whole ring cycle (easily tens of seconds) - that's not an error, though a short timeout on your side could look like one while the call is still ringing.

4Troubleshooting

The most common messages with your own agent, and what to do about them:

MessageCauseFix
1011 sip request timed outThe outbound trunk address is not outboundTrunkAddress.Set ElevenLabs outbound_trunk_config.address to outboundTrunkAddress from the SIP credentials response, not to server.
SipCallTo should be a phone number or SIP user, not a full SIP URIto_number contains the full sipUri instead of the bare name.Only sipName from the POST /v1/relay response belongs in to_number.
The call fails right away on the platform (failed on ElevenLabs), nothing on our sideYou dialed the phone number directly, not through the relay.Create a relay connection (POST /v1/relay) and dial the returned sipName.
404 from_number_not_ownedfrom in POST /v1/relay is not your own volai number.Set from to exactly the volai number you're calling from.
400 relay_lease_limitAn active lease is already running on this number (1) or account (2).Wait for the lease to free up, or cancel an unused one (DELETE /v1/relay/{id}).
503 capacity_busyThe shared relay slot pool is temporarily full.Nothing is billed - try again shortly.
Inbound calls don't ringThe number isn't imported in ElevenLabs, allowed_addresses doesn't allow our range, or routing isn't saved on volai.Check all three steps above; if the PBX challenges with 401, fill in the username and password on the routing.
The callee sees the volai line instead of yoursThe number doesn't have its own relay names yet.Contact support - relay names get set up on your line and the caller ID gets fixed.

5Billing

An outbound call through the relay is billed at the same rate as a regular outbound call - 0.92 CZK/min (~EUR 0.04) - with no agent surcharge whatsoever. Rates exclude VAT, like the whole price list.

Concurrency is limited (see the limits below): at most 1 active call per one of your numbers, and at most 2 per account at once.

The callee only sees your volai line if the number has its own relay names (relayNames) - without them, the lease falls back to the shared pool and the callee sees volai's demo number. If you're missing relay names, contact support.

6Limits, quotas and security

The cap is 1 active lease per number and at most 2 per account - a deliberate safeguard against one customer occupying the entire shared relay slot pool:

WhatValue
Lease waiting for the first call (pending)120 s default, ttlSecs 15 to 300 s
Call in progress (active)15 minutes
Active lease per one of your numbersat most 1
Active leases per accountat most 2
Lease usageone-time - a second call on the same lease is rejected
  • from must be your own volai number - otherwise from_number_not_owned. Without this check, you could spoof someone else's line as your caller ID.
  • Same gates as a regular call - do-not-call list (calls only, not SMS), automatic 30-day block after 3 failed attempts to the same number within 24 hours, premium-rate lines, protection against loops between volai numbers, the callee-number lock, and the general call rate limit. None of this can be bypassed through the relay.
  • Pool full -> 503 capacity_busy - relay slots are a shared concurrency cap for the WHOLE platform, not just your account. On capacity_busy nothing is billed, try again shortly.
  • The full REST reference (error codes, GET/DELETE on leases) is in the REST API reference.

Every API error carries cause (who fixes it) and action (what to do) - see Error format in the REST API reference.