Guides

Twilio and Plivo

Use your own Twilio or Plivo account for numbers and live calls through media streams.

Twilio and Plivo are the two providers the platform can dial through directly and buy numbers from. Both carry the call's audio to the voice engine as a media stream over a WebSocket.

Warning: The Twilio and Plivo code paths are tested against local fakes and a mock dialer. No call has been placed through either provider on a real account. Run your first calls as a test, to a number you own.

What you need

  • Your own Twilio or Plivo account with a voice-capable number, or an operator who supplies platform-wide credentials.
  • An operator running the platform in live telephony mode, with a public https address for the API and a public wss:// address for the voice engine.
  • An agent on the own engine.

In mock telephony mode (the default) none of this is used: dialling is recorded, not performed. See Testing without a phone.

Add your provider keys

Keys are stored per account, one request per key. They are encrypted at rest. Adding keys needs the admin role or an API key. In the dashboard: Settings → Integrations.

bash
curl -X POST https://api.sevennadi.si/providers \
  -H "Authorization: Bearer vk-0123456789abcdef0123456789abcdef" \
  -H "Content-Type: application/json" \
  -d '{"provider_name": "TWILIO_ACCOUNT_SID", "provider_value": "<your account SID>"}'
json
{"message": "successful", "status": "added"}
Providerprovider_name values
TwilioTWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN
PlivoPLIVO_AUTH_ID, PLIVO_AUTH_TOKEN

Sending a name again replaces its value. GET /providers lists them with only the last two characters visible:

json
[{"provider_id": "0e1f2a3b-4c5d-4e6f-8a9b-0c1d2e3f4a5b", "provider_name": "TWILIO_ACCOUNT_SID",
  "provider_value": "xxxxxxx9f", "humanized_created_at": "just now", "created_at": "2026-10-13T10:20:00Z"}]

DELETE /providers/{provider_key_name} removes one. Your account's keys take precedence over the platform's.

Set the agent's provider

bash
curl -X PATCH https://api.sevennadi.si/v2/agent/3c90c3cc-0d44-4b50-8822-8dd25736052a \
  -H "Authorization: Bearer vk-0123456789abcdef0123456789abcdef" \
  -H "Content-Type: application/json" \
  -d '{"agent_config": {"telephony_provider": "plivo"}}'

This sets tools_config.input.provider and output.provider on every task, with audio format wav.

The agent must also run on the own engine. Put "engine": "own" in agent_config when you create or replace the agent, or send "agent_data": {"engine": "own"} with each call.

Numbers

In live mode, GET /phone-numbers/search and POST /phone-numbers/buy query and rent numbers at the provider with your keys. The default provider is Twilio for US and Plivo for IN; pass provider to choose. Without credentials:

text
No plivo credentials: add PLIVO_AUTH_ID and PLIVO_AUTH_TOKEN via POST /providers

A number you already have can be registered with POST /phone-numbers/import. See Inbound and numbers.

How an outbound call runs

  1. POST /call creates the execution. A worker admits it against your concurrency limit.
  2. The platform asks the provider to dial, giving it an answer URL and a status URL. Both carry a token tied to that one call.
  3. When the recipient answers, the provider fetches the answer URL. The platform replies with instructions to stream the call's audio to the engine.
  4. The provider posts progress to the status URL: ringing, in progress, then completed (with the duration), busy, no-answer or failed. These become the execution's statuses and your webhooks.
  5. The engine reports turns, usage and a final result. After the provider says the call is over, the platform waits a short time for that result, then computes the transcript, cost, summary and extraction and marks the execution completed.

Calls are dialled with recording and answering-machine detection switched on at the provider.

Media streams

TwilioPlivo
Stream typeMedia StreamsAudio Streams, bidirectional
Audiobase64 μ-law, 8 kHzbase64 μ-law, 8 kHz
How the call is identifiedStream parameters execution_id and tokenQuery parameters on the stream URL
Interrupting the agentA clear eventA clearAudio event

The engine converts to 16-bit PCM internally. More in Engine protocol.

Inbound calls

Link an agent to the number with POST /inbound/setup. The response contains a url; set it as the number's voice webhook at the provider. When the number is dialled, the platform creates an inbound execution and answers with the same stream instructions as step 3 above.

Stopping and transferring

  • POST /call/{execution_id}/stop hangs the call up through the provider; the execution ends stopped.
  • When an agent's transfer_call tool fires, the platform redirects the live call to dial the destination number. The engine waits a few seconds for the provider to take the call away, then ends its side. The execution carries transfer_call_data.

What the operator configures

  • Live telephony mode and the public https address of the API. Providers and the engine both call it.
  • The engine's public media-stream address.
  • Optionally platform-wide Twilio or Plivo credentials, used when an account has none.

See Deployment.

Limitations

  • No real call has been made on Twilio or Plivo. Transfer by redirect has not been tried on a live call either.
  • Answer and status callbacks are authorised by the per-call token in their URL; the provider's request signature is not checked on those. The inbound-call webhook does check it: see Inbound calls and numbers.
  • Search and buy cover US and IN only.
  • The mock engine cannot take real calls: an agent must use the own engine in live mode.
  • With an engine at capacity, an inbound call is refused before it is answered, silently. Configure a fallback at the provider.