Place phone calls from Python in a few lines.
Text-to-speech calls · press-1 voice broadcasts · live AI voice agents · auto local-presence caller ID.
voicepilot is the official Python SDK for the Zcall voice API. Sign up, grab an API key, add a little balance, and start dialing — no PBX, SIP trunk, or carrier contract. A developer-friendly, pay-as-you-go alternative to Twilio, Vonage, Plivo, and Bland.
Why voicepilot
- 📞 Real outbound calls from code — one function, one call. Or a whole list.
- 🗣️ Text-to-speech — speak any message; pick a voice and language.
- ☎️ Press-1 voice broadcasts — blast a message and transfer anyone who presses 1 to a live agent.
- 🤖 Live AI voice agents — natural, real-time conversations that qualify leads, confirm bookings, or take messages.
- 🌍 Auto local-presence caller ID — omit the caller ID and each call presents a number in the destination's own country (answered far more often).
- ⚡ Guaranteed-CLI routes to 100+ destinations, crypto-friendly, pay-as-you-go.
Install
pip install voicepilot
Requires Python 3.8+ and requests.
Quickstart
- Create an account at zcall.io and copy your API key (Dashboard → Settings → API).
- Add a little balance.
- Place a call:
from voicepilot import VoicePilot
vp = VoicePilot(api_key="zc_live_...") # or set the VOICEPILOT_API_KEY env var
# Text-to-speech call. No caller_id -> a local-presence number for the
# destination's country is chosen automatically.
batch = vp.calls.say(
to="+14155551234",
message="Hi! This call was placed from Python with voicepilot.",
)
print(f"launched {batch.launched}/{batch.total} from {batch.caller_id}")
Features
🗣️ Text-to-speech calls
Call one number or many. Pass a voice_id / language to control how it sounds.
vp.calls.say(
to=["+14155551234", "+447700900123"],
message="Your appointment is confirmed for Tuesday at 3 PM.",
language="en",
)
☎️ Press-1 voice broadcast (P1)
Broadcast a spoken message to a list; anyone who presses 1 is transferred to your agent SIP user(s) — tried in order, first online wins.
batch = vp.calls.say(
to=["+14155551234", "+447700900123", "+9779812345678"],
message="This is a courtesy call about your account. Press 1 to speak with us.",
press1_transfer_to=["1001", "1002"],
)
# With no caller_id, each country gets its own local-presence caller ID.
print(f"{batch.launched} calls across {len(batch.campaigns)} caller IDs")
🤖 Live AI voice agent
A real-time AI agent driven by your prompt. It talks, listens, and can hand off to a human.
vp.calls.ai(
to="+14155551234",
prompt="You are a friendly clinic receptionist. Confirm the caller's "
"appointment for Tuesday at 3 PM and offer to reschedule.",
first_message="Hi, this is Riverside Clinic calling to confirm your appointment.",
transfer_to=["1001"], # if the caller asks for a human
# elevenlabs_api_key="sk_...", # optional: run on your own ElevenLabs account
)
🌍 Automatic local-presence caller ID
Leave caller_id out and voicepilot presents a number matching each destination's country. You can also generate one yourself:
from voicepilot import local_presence_caller_id
local_presence_caller_id("+447700900123") # -> "+44…" (a UK number)
local_presence_caller_id("+14155551234") # -> "+1…" (a US number)
Acceptable use. Only present a caller ID you are authorised to use, and follow the caller-ID and telemarketing rules for everywhere you call and call from (e.g. US TRACED Act / TCPA, UK Ofcom CLI, EU/GDPR). You are responsible for how you use this.
📊 Results & account
for row in batch.results(): # per-call status + DTMF (1 = pressed)
print(row["destination"], row["status"], row.get("dtmf"))
vp.calls.stats() # totals + answer rate
vp.balance() # live balance
vp.rates() # live per-minute rates (no auth needed)
vp.voices("en") # available voices
Pricing
Pay-as-you-go — no subscription, no minimums, and your balance never expires.
| What | Price |
|---|---|
| Create an account | Free |
| Outbound & TTS calls | from $0.05 / min — varies by destination |
| Press-1 voice broadcast | standard per-minute call rate |
| Live AI voice agent | $0.30 / min — or no surcharge with your own ElevenLabs key |
| Subscription / minimums | None — prepaid, balance never expires |
| Payment | Cards & crypto · billed in USD |
Rates are indicative. See live per-destination pricing at zcall.io.
API reference
| Method | Description |
|---|---|
vp.calls.say(to, message, *, caller_id=None, voice_id=None, language="en", press1_transfer_to=None) |
TTS call to one/many numbers; press-1 transfer |
vp.calls.ai(to, prompt, *, first_message=None, transfer_to=None, elevenlabs_api_key=None, ...) |
Live AI voice-agent call |
vp.calls.launch(flow_id, to, *, caller_id=None) |
Launch a saved flow |
batch.results() · vp.calls.results(campaign_id) |
Per-call status + DTMF |
vp.calls.stats() |
Answer-rate / totals |
vp.flows.create(...) · .list() · .delete(id) |
Manage reusable flows |
vp.balance() |
Live account balance |
vp.rates() |
Live per-minute rates (no auth) |
vp.voices(lang) · vp.languages() |
Available voices / languages |
vp.set_caller_id(cid) |
Set your default outbound caller ID |
Full REST reference: zcall.io/docs.
Error handling
Every error subclasses VoicePilotError:
from voicepilot import VoicePilot, AuthenticationError, InsufficientBalanceError
try:
vp.calls.say(to="+14155551234", message="Hello")
except InsufficientBalanceError:
print("Top up your balance at zcall.io")
except AuthenticationError:
print("Check your API key")
Links
- 🌐 Website — zcall.io
- 📚 API docs — zcall.io/docs
- 💬 Support (Telegram) — t.me/zcall_admin
License
MIT © Zcall. See LICENSE.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file voicepilot-0.1.0.tar.gz.
File metadata
- Download URL: voicepilot-0.1.0.tar.gz
- Upload date:
- Size: 14.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/7.0.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
eea34fb4fb3d9ef57ad8f763d2c44231ecc04845674d26230680fbbb0a003135
|
|
| MD5 |
86452775f918176c4937ef26a9044d83
|
|
| BLAKE2b-256 |
ff64aefaa014286cc6cbb7f53708da3572bf3f4058775d26d72d3a315d1ec1a5
|
File details
Details for the file voicepilot-0.1.0-py3-none-any.whl.
File metadata
- Download URL: voicepilot-0.1.0-py3-none-any.whl
- Upload date:
- Size: 12.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/7.0.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7d18b8ded59b8208c77d90828ca2841de42102fb9636566942d398e74f6c435f
|
|
| MD5 |
f36dfb3e3eec5605f72479979caee3f1
|
|
| BLAKE2b-256 |
1cf0d675422ba2f84a8384c494beaaa74755d13c2fa5c1c124af5dde4ba12e7a
|