Dial
pilotctl appstore install io.pilot.dialAbout Dial
Dial gives your agent its own real phone number: place and receive AI voice calls, send and receive SMS and iMessage, and wait on inbound events without polling. Bring your Dial API key at install time and every method authenticates as your own account. The account is yours, works outside Pilot too, and starts with $5 of credit and no credit card. No key yet? dial.signup emails a 6-digit code and dial.verify exchanges it for one. What you can do - Call people. dial.place_call runs an autonomous AI voice call from your number: book a table, chase a delivery, return a missed call. Pass transferTo and it waits out hold music and IVR menus, then cold-transfers to your human the moment a real person answers — never to a recording. Poll dial.get_call for the transcript, or block on dial.wait_for_event. - Give the call your tools. Connect a Context MCP and your MCP server tools become available to the voice agent DURING the call, so it can look something up or take an action mid-conversation. Dial runs the OAuth 2.1 flow and keeps the token fresh in the background. - Text people. dial.send_message delivers over iMessage when the recipient supports it and falls back to SMS otherwise, same call either way. Show a typing indicator first with dial.typing. - Wait, do not poll. dial.wait_for_event blocks until an inbound reply, a 2FA code, or a finished call shows up. A 408 means try again, not an error. - Own the identity. Set each number inbound behavior, voice and language, and on iMessage numbers the display name and avatar recipients see in Messages. Cost Reads are free. $3/month per number. US SMS $0.02 per segment. Managed voice $0.22/min all-in; self-hosted voice $0.13/min if you bring your own LLM over a WebSocket. Your $5 signup credit covers the first usage and spend pauses at $0 rather than surprising you. Good to know A brand-new account is on the free tier until it is topped up, which caps calls at 5 minutes and 2 concurrent calls. Both lift permanently on the first top-up. Emergency and crisis numbers are blocked. Always pass numbers in E.164, e.g. +14155551234. Every method, its parameters and latency class are discoverable at runtime via dial.help.
Methods · 20
dial.statusdial.usagedial.signupdial.verifydial.list_numbersdial.buy_numberdial.get_numberdial.set_numberdial.release_numberdial.send_messagedial.list_messagesdial.typingdial.place_calldial.get_calldial.list_callsdial.end_calldial.wait_for_eventdial.list_context_mcpsdial.add_context_mcpdial.remove_context_mcpFull usage demo
When a task needs a phone: call a business and sit through the hold queue, text someone and wait for the reply, or receive a 2FA code on a real US number.
pilotctl appstore call io.pilot.dial dial.status '{}'{"credit":"$5.00","plan":"free","maxCallDurationSeconds":300,"maxConcurrentCalls":2}Free. A new account starts with $5 and no card. No key yet? dial.signup emails a code and dial.verify exchanges it for one.
Worked examples
pilotctl appstore call io.pilot.dial dial.buy_number '{"areaCode":"415","explicitProgrammaticConsent":"yes"}'{"id":"num_...","phoneNumber":"+14155550123"}Spends money, so it requires an explicit consent attestation — confirm with your human first. Then dial.send_message delivers over iMessage when the recipient supports it, else SMS.
pilotctl appstore call io.pilot.dial dial.place_call '{"to":"+14155550199","fromNumber":"+14155550123","outboundInstruction":"Ask if they take reservations for 4 at 8pm Friday","transferTo":"+14155550100"}'{"id":"call_...","status":"queued"}transferTo hands the live call to your human the moment a real person answers — never to a recording. Poll dial.get_call for the transcript.
pilotctl appstore call io.pilot.dial dial.wait_for_event '{"eventType":"message.received","timeout":120}'{"event":"message.received","message":{"body":"Your code is 481920"}}A 408 means try again, not an error. This is how you catch a 2FA code without spinning.
What it costs
| Operation | Price | Notes |
|---|---|---|
reads (status, usage, list_*, get_call, wait_for_event) | free | |
dial.buy_number | $3.00/month | requires an explicit consent attestation |
dial.send_message | $0.02 per SMS segment | iMessage delivery where supported |
dial.place_call | $0.22/min | $0.13/min self-hosted if you bring your own LLM |
$3.44 — one number for a month ($3.00), one 2-minute call ($0.44), reads free. Inside the $5 signup credit.
Good to know
- Reads are free; buying a number, texting and calling cost money. Check dial.status first.
- dial.buy_number needs an explicit consent attestation because it spends — confirm with your human.
- A new account is capped at 5-minute calls and 2 concurrent until the first top-up.
- Always pass numbers in E.164, e.g. +14155551234. Emergency and crisis numbers are blocked.
- Prefer dial.wait_for_event over polling; a 408 means retry, not failure.
Next
io.pilot.dial dial.help '{}'
What’s New
- First release on the Pilot app store.