AgentCall

Give your agent real phone numbers for SMS, OTP verification, and voice calls via the AgentCall API.

Audits

Pass

Install

openclaw skills install agentcall

AgentCall: Phone Numbers for AI Agents

You have access to the AgentCall API for phone numbers, SMS, voice calls, and AI voice calls. Inbound and outbound calls can both be answered or initiated by an AI voice agent.

Authentication

All authenticated requests require: Authorization: Bearer <AGENTCALL_API_KEY>

The API key is available in the AGENTCALL_API_KEY environment variable.

Base URL

https://api.agentcall.co

For a complete plain-text API reference: GET https://api.agentcall.co/llms.txt (no auth required).

Cost & Safety: Confirm Before Acting

Several tools below take real-world actions on the user's behalf. Confirm with the user before invoking them, and stay within the scope of what they explicitly asked you to do.

Billable actions (cost real money. Confirm scope first):

  • POST /v1/numbers/provision: recurring monthly cost ($2.00–$2.50/month depending on type). Confirm the user wants a new number; ask which type, country, and label before provisioning.
  • POST /v1/sms/send: $0.015/message on Pro (10/month free on Free plan). Confirm the recipient number and the message body before sending.
  • POST /v1/calls/initiate: $0.035/min on Pro. Confirm the destination number and purpose before dialing. Optional record: true adds $0.01/min on top.
  • POST /v1/calls/ai: $0.40/min on Pro. Confirm the destination, the system prompt, and maxDurationSecs before dialing. Outbound AI calls reach a real human and accumulate cost per minute.
  • Inbound AI voice (POST /v1/numbers/:id/inbound-config with mode: "ai"). Free tier includes 5 minutes/month with no card required. Once the trial is exhausted, additional inbound AI calls hang up at the carrier with status trial_exhausted until the trial resets on the 1st of next month (UTC), OR until the user upgrades to Pro for unlimited inbound AI at $0.40/min on every incoming call. There is no pay-as-you-go overage path on Free. Confirm the user wants inbound AI enabled on this specific number, and that the system prompt accurately describes their business.
  • Optional record: true on AI voice paths. $0.01/min on top of the AI rate. Mention this delta when proposing recording.

Irreversible actions:

  • DELETE /v1/numbers/:id: releases the number permanently. The same number cannot be re-provisioned. Always confirm before releasing, and warn the user that this is irreversible.
  • POST /v1/calls/:callId/hangup: terminates an in-flight call. Usually fine but confirm if the call may still be progressing toward its goal.

External-effect actions (contact real people):

  • Sending SMS, initiating outbound calls, and AI voice calls reach real recipients on real networks. Don't initiate these speculatively. The receiving party should be expecting contact, or the user should explicitly authorize the outreach.
  • For two-party-consent states (CA, FL, IL, MD, MA, PA, WA, NV, NH, MT, CT, DE), recording requires disclosure. AgentCall auto-prepends "This call may be recorded for quality." to the spoken firstMessage when record: true is set on AI voice paths and the message doesn't already mention recording. But you should still mention recording in firstMessage content for clarity if the user is writing one from scratch.

Built-in API guardrails (don't rely on these as your only check):

  • Free plan hard caps: 1 local number, 10 SMS/month, 5 voice minutes/month, 5 inbound AI voice minutes/month (no card required for the trial), 5 OTP extractions/month. Prevents runaway spend on the free tier.
  • Outbound AI voice + call recording require a payment method on file (Pro plan). The API returns 402 with a setupUrl if a Pro user has no card. Surface this to the user instead of looping.
  • Inbound AI voice past the 5-minute Free trial requires upgrading to Pro. The API returns 403 plan_limit_inbound_ai_trial_exhausted with an upgradeUrl. There is no pay-as-you-go overage path on Free; the trial resets on the 1st of each month (UTC).
  • Rate limits: 100 req/min global; per-route limits on expensive endpoints (10 req/min on AI voice, 20 req/hour on uploads).
  • Carrier restrictions: AI voice (in or out) and inbound AI configuration are US/Canada-only; the API returns 400 carrier_not_supported for other countries.

Inbound AI Configuration: Enable Only After Explicit User Confirmation; Monitor Usage; Disable When No Longer Needed

configure_inbound_ai and POST /v1/numbers/:id/inbound-config with mode: "ai" should follow this procedure every time:

Pre-flight checklist (require the user to confirm each before invocation):

  1. The exact E.164 number to configure. Read it back if the user has more than one number.
  2. The system prompt content. Read back at least the WHAT WE DO and PRICING sections so the user can correct anything inaccurate before invocation.
  3. The recording setting (record: true or false). Default to false. Confirm explicit opt-in if the user wants recording.
  4. The notification email (notify.emailTo). Confirm the address belongs to the user and that they want post-call summaries delivered to it.
  5. The shortest practical call duration (maxDurationSecs). Pick the smallest value that fits the use case rather than relying on the 600-second default.
  6. The budget expectation: Free 5 minutes/month with carrier hang-up after exhaustion, or Pro at $0.40/min with no monthly cap. Tell the user which applies and what their expected monthly bill is.

Post-configuration responsibility:

  • Monitor usage: periodically call get_usage or point the user at the dashboard at /billing.
  • Disable as soon as the configuration is no longer needed: proactively offer disable_inbound_ai (or DELETE /v1/numbers/:id/inbound-config) when the user's stated goal has been met (testing finished, campaign over, business closed for the season).
  • If the user reports unexpected calls or charges, call disable_inbound_ai first, then investigate.

If the user's request is ambiguous (e.g. "set up a phone number" with no type or country, or "send a text" with no recipient), ask one or two clarifying questions before invoking a billable tool.

Phone Numbers

Provision a number:

POST /v1/numbers/provision
Body: { "type": "local", "country": "US", "label": "my-agent" }
Types: local ($2/mo), tollfree ($2.50/mo), mobile ($2/mo). All numbers are VoIP-routed via licensed US carriers; not for consumer-platform signup verification (Stripe, WhatsApp, Google, banks).
Response: { "id": "num_xxx", "number": "+12125551234", "type": "local", ... }

List numbers:

GET /v1/numbers
Query: ?limit=20&country=US&type=local

Get number details:

GET /v1/numbers/:id

Release a number (irreversible):

DELETE /v1/numbers/:id

Rename a number or change its inbound AI voice (partial update, preserves all other inbound config):

PATCH /v1/numbers/:id
Body: { "label": "Hermes assistant" }                  // rename only
Body: { "voice": "marin" }                             // voice only (requires inbound AI already configured)
Body: { "label": "Hermes", "voice": "coral" }          // both at once
Voices: alloy, ash, ballad, cedar, coral, echo, marin, sage, shimmer, verse
Response: full number object including updated `inbound` block.

Use this when the user wants to change the voice on an existing receptionist. Do NOT call POST /v1/numbers/:id/inbound-config for a voice change — that endpoint replaces the entire inbound config and would wipe the system prompt, first message, recording flag, and notify block.

Inbound AI Voice (Free 5 min/month trial, then $0.40/min with card or Pro plan; US and Canada numbers only)

Configure a phone number so incoming calls are answered autonomously by an AI voice agent. The AI follows the system prompt you set.

After every call, AgentCall summarizes the transcript with an LLM and emails a plain-English summary. Caller name (when given), phone, urgency tag, and a 1-2 sentence ask. To an address you configure on the number. Spam calls are auto-suppressed from the email. The structured call.transcript webhook event still fires in parallel for programmatic consumers.

Configure inbound AI on a number:

POST /v1/numbers/:numberId/inbound-config
Body: {
  "mode": "ai",
  "systemPrompt": "You are the front desk for Acme Plumbing. Greet the caller warmly, take their name and a brief description of the issue, then say someone will call back within 24 hours.",
  "voice": "shimmer",
  "firstMessage": "Hi, thanks for calling Acme Plumbing. How can I help?",
  "maxDurationSecs": 300,
  "notify": {
    "emailTo": "owner@acmeplumbing.com",
    "businessName": "Acme Plumbing",
    "agencyName": "Acme Plumbing"
  }
}

The notify block is optional. Set notify.emailTo to receive the post-call summary email; businessName is shown in the email subject; agencyName is the sign-off line. The MCP configure_inbound_ai tool also accepts notify: agents in Claude Desktop, Cursor, Windsurf, etc. can configure the email destination in the same call as the system prompt, no dashboard handoff needed.

Pre-call context webhook (optional): add a contextWebhook block to wire a live context source onto the number. When set, AgentCall POSTs to your HTTPS URL on every inbound call connect (HMAC-signed with signingSecret); your endpoint responds with {"contextBlock":"..."} and AgentCall merges that string onto the system prompt before the AI answers. Useful for injecting today's brief, current priorities, or recent email signals so the AI speaks with up-to-date data instead of a static prompt. Example:

"contextWebhook": {
  "url": "https://hermes.your-domain.com/agentcall/precall",
  "signingSecret": "<32+ char shared secret>",
  "timeoutMs": 1200
}

Fail-open: any error in the webhook leaves the call running with the static prompt. Walkthrough at https://agentcall.co/docs/hermes.

Optional call recording (Pro plan, $0.01/min on top of the AI voice rate): Add record: true to the body above (or flick the toggle on the dashboard's /numbers config form) to record every inbound call to this number. Recordings live in your AgentCall dashboard for 1 year and are listenable from the Logs → Calls tab or via GET /v1/calls/:callId/recording (returns a fresh short-lived signed URL). The call.recording webhook fires when each recording is ready. The same record flag is supported on outbound AI voice (POST /v1/calls/ai). When recording is on, AgentCall auto-prepends a TCPA-compliant disclosure to the spoken firstMessage if it doesn't already mention recording.

Get current inbound config:

GET /v1/numbers/:numberId/inbound-config

Disable inbound AI (calls hang up at carrier):

DELETE /v1/numbers/:numberId/inbound-config

Browse Voices and Prompt Templates (no auth)

Both endpoints are public. Call them before configuring AI voice to avoid hallucinated business details and to pick a voice that fits the use case.

List the 10 voices with samples:

GET /v1/calls/voices
Returns: { voices: [{ id, name, trait, description, bestFor, sampleUrl? }, ...], defaultVoice: "shimmer" }

The newest natural-sounding picks are marin (soft, natural) and cedar (warm, grounded). The original 8 (shimmer, sage, ash, ballad, coral, echo, verse, alloy) ship with sample MP3s; marin and cedar are live-preview only for now.

List ready-made prompt templates:

GET /v1/calls/prompt-templates
Returns 5 templates with [BRACKETED] placeholders to fill in:
- receptionist (Front Desk). Recommends shimmer voice
- lead-qualifier (Sales, BANT-style). Coral
- appointment-booker. Sage
- customer-support (FAQ Deflection). Ash
- call-screener (Anti-Spam). Verse
Each entry includes: id, title, description, recommendedVoice, maxDurationSecs, firstMessage, systemPrompt.

For a comprehensive prompt-writing guide: https://agentcall.co/docs/voice-prompts

SMS

Send SMS:

POST /v1/sms/send
Body: { "from": "num_xxx", "to": "+14155551234", "body": "Hello!" }
"from" can be a number ID or E.164 phone string

Get inbox:

GET /v1/sms/inbox/:numberId
Query: ?limit=20&otpOnly=true

Get a specific message:

GET /v1/sms/:messageId

Wait for OTP code (long-polls up to 60 seconds):

GET /v1/sms/otp/:numberId
Query: ?timeout=60000
Response: { "otp": "482913", "message": { ... } }

Outbound Voice Calls

Start a standard outbound call:

POST /v1/calls/initiate
Body: { "from": "num_xxx", "to": "+14155551234", "record": false }

Start an outbound AI voice call (Pro plan, $0.40/min. Billable, contacts real human, confirm with user first): The AI handles the entire conversation autonomously based on your systemPrompt.

POST /v1/calls/ai
Body: {
  "from": "num_xxx",
  "to": "+14155551234",
  "systemPrompt": "You are calling to schedule a dentist appointment for Tuesday afternoon.",
  "voice": "shimmer",
  "firstMessage": "Hi, I'd like to schedule an appointment please.",
  "maxDurationSecs": 600,
  "record": false
}

Add record: true to capture an mp3 of the call. Adds $0.01/min on top.

Voices (10 total, default: shimmer; preview the original 8 via GET /v1/calls/voices, marin and cedar are live-preview only):

  • marin: soft, natural. New top pick for receptionist, support, conversational small business
  • cedar: warm, grounded. New. Advisory, healthcare, trust-building calls
  • shimmer: bright, energetic. Long-running default
  • sage: calm, authoritative, confident. Healthcare, finance, advisory
  • ash: warm, conversational. Customer service, support lines
  • ballad: expressive, melodic. Engaging, narrative conversations
  • coral: clear, professional. B2B calls, sales
  • echo: resonant, deep. Formal inquiries, executive comms
  • verse: smooth, articulate. Premium or luxury, executive communication
  • alloy: neutral, balanced. Generic notifications, IVR-style flows

List call history:

GET /v1/calls
Query: ?limit=20

Get call details:

GET /v1/calls/:callId

Get AI call transcript:

GET /v1/calls/:callId/transcript
Response: { "entries": [{ "role": "ai" | "human", "text": "...", "timestamp": "..." }], "summary": "...", "duration": 111 }

Hang up an active call:

POST /v1/calls/:callId/hangup

Webhooks

Important: webhooks here are for OUTBOUND event delivery, NOT inbound call routing. AgentCall POSTs to your URL when events fire (SMS received, OTP detected, call completed, recording ready, etc.). Webhooks are NOT how you make a phone number answer incoming calls. To configure how a number answers when called, use the Inbound AI Voice section above (POST /v1/numbers/:numberId/inbound-config). Not webhooks. (If you're coming from Twilio: AgentCall replaces Twilio's inbound voice webhook URL with configure_inbound_ai.)

Register a webhook:

POST /v1/webhooks
Body: { "url": "https://example.com/hook", "events": ["sms.inbound", "sms.otp", "call.status"] }
Events: sms.inbound, sms.otp, call.inbound, call.ringing, call.status, call.recording, call.transcript, number.released

List webhooks:

GET /v1/webhooks

Rotate webhook secret:

POST /v1/webhooks/:id/rotate

Delete a webhook:

DELETE /v1/webhooks/:id

Usage & Billing

Get usage breakdown:

GET /v1/usage
Query: ?period=2026-04

Pricing (per use, Pro plan):

  • SMS outbound: $0.015/msg
  • SMS inbound: $0.008/msg
  • Voice (standard outbound): $0.035/min
  • Voice (standard inbound): $0.015/min
  • AI voice (outbound): $0.40/min
  • AI voice (inbound): $0.40/min
  • Call recording: $0.01/min

Phone Number Format

All phone numbers must be E.164: +{country code}{number}, e.g. +14155551234

Common Workflows

Set up an AI receptionist on a phone number

  1. POST /v1/numbers/provision with { "type": "local" }: get a number
  2. GET /v1/calls/prompt-templates: pick a template (e.g. "receptionist")
  3. Replace [BRACKETED] placeholders with the customer's real business details
  4. POST /v1/numbers/:numberId/inbound-config with { "mode": "ai", "systemPrompt": "...", "voice": "shimmer", "firstMessage": "..." }
  5. Anyone who calls the number is now answered by the AI agent
  6. GET /v1/calls to see incoming call history; GET /v1/calls/:callId/transcript for transcripts

Test your app's SMS verification (QA)

  1. POST /v1/numbers/provision with { "type": "local" }: get a test number
  2. Enter the number into your staging app's verification form
  3. GET /v1/sms/otp/:numberId?timeout=60000: wait for the verification code
  4. Assert the code arrives and your app accepts it
  5. DELETE /v1/numbers/:id: release the test number

Make an outbound AI voice call

  1. POST /v1/numbers/provision with { "type": "local" }: get a number (if you don't have one)
  2. POST /v1/calls/ai with { "from": "num_xxx", "to": "+1...", "systemPrompt": "..." }: start the call
  3. Wait for the call to complete
  4. GET /v1/calls/:callId/transcript: get the full conversation transcript

Error Codes

  • 401: Invalid or missing API key
  • 402 payment_method_required: Add a card before configuring billable features (returns setupUrl to Stripe Checkout)
  • 403 plan_limit_voice_ai: Outbound AI voice requires Pro plan ($19.99/mo).
  • 403 plan_limit_inbound_ai_trial_exhausted: Free user has used up their 5-minute monthly inbound AI trial. Returned with upgradeUrl. Trial resets on the 1st of next month (UTC) or the user can upgrade to Pro for unlimited inbound AI.
  • 403 plan_limit_*: Other plan limits. Upgrade at agentcall.co/dashboard
  • 400 carrier_not_supported: Inbound AI voice is only supported on US and Canada numbers
  • 404: Resource not found
  • 422: Validation error (check request body)
  • 429: Rate limit exceeded (100 req/min global; per-route limits on expensive endpoints)
  • 503 voice_ai_unavailable: Server-side AI voice infrastructure issue. Retry later