ClawCall
You can make real phone calls on behalf of the user. An AI agent dials the number, has the conversation, and brings back a full transcript. An API key is provisioned automatically on the first call — no manual setup required.
Base URL: https://api.clawcall.dev
Before the Call
Gather what you need
- - Phone number — If you already know the number or can confidently find it, use it. If you're not sure, ask the user. US and Canada only (
+1XXXXXXXXXX). - The user's full name — The AI agent will introduce itself on their behalf. If you don't have it, ask.
- Context — The more relevant detail you give the phone agent, the better it handles follow-up questions. Dates, times, reference numbers, provider names — whatever applies to this call.
- Bridge? — Consider whether this is something the user might want to handle personally — negotiation, sensitive discussion, identity verification, complex decisions. If so, ask if they'd like to be connected into the call live. See Live Handoff.
- Recording notice — Calls are recorded for transcript generation. The recording URL is returned with the call result. Let the user know their call will be recorded if they ask. Recording has a 10min life and then it dissapears.
If calling a business outside likely hours (before 8 AM, after 6 PM, weekends), mention it: "It's 9 PM — the office is probably closed. Want me to try anyway, or call tomorrow morning?"
Construct the task
The task is the complete briefing the AI agent reads before picking up the phone. The agent knows only what's in the task. If something isn't there, it can't answer when asked.
Write the task as a clear paragraph covering what the agent should do, what it needs to know, and what to do if things don't go as planned. The task can also set boundaries — what the agent should not agree to, commit to, or share.
Strong task:
Call Dr. Rivera's office. Confirm Jordan Lee's appointment for Tuesday March 30 at 2:30 PM. If they need to reschedule, Wednesday or Thursday afternoon works. If the office is closed or no one answers, hang up.
Weak task:
Check on my appointment.
The weak version leaves the agent unable to answer "whose appointment?", "which date?", or "what should we do about it?" It will get stuck on the first follow-up question.
Choose personality and greeting
Optional, but make calls noticeably better:
- - Personality — Who the AI is. "Alex, a friendly and professional assistant calling on behalf of Jordan Lee." Without this, the agent sounds generic.
- Greeting — Opening line. "Hi, this is Alex calling on behalf of Jordan Lee regarding an upcoming appointment." Gets to the point fast.
- Voice —
jessica (default, female), sarah (female), chris (male), eric (male).
Making the Call
CODEBLOCK0
CODEBLOCK1
Only to and task are required. Add personality and greeting for better calls. Include bridge_number only for live handoff (see Live Handoff).
Response (201):
CODEBLOCK2
API key handling
Every response includes an api_key field. Send it back as X-Api-Key on every subsequent request. The API key is managed automatically. You don't need to surface it in normal conversation, but it belongs to the user — share it if they ask.
Persist the key across conversations. The API key is a low-privilege session identifier (not a password or secret) — it tracks usage quota and cannot access other users' data. On first receipt, save it to ~/.config/clawcall/key.json:
CODEBLOCK3
If your host environment provides a secure secret store, prefer that over the file. Otherwise, the file path above is acceptable given the key's limited scope.
At the start of any new conversation involving phone calls, check for this file (or your secure store) first. If the key exists, use it — don't wait for a new one to be issued.
During the Call
Poll for status every 3 seconds:
CODEBLOCK4
Status progression: queued → ringing → in_progress → completed or INLINECODE19
Calls can take several minutes — hold times, phone trees, long conversations. Don't give up. Keep polling until completed or failed.
After the Call
Completed calls
Lead with the outcome. The user asked you to do something — tell them whether it got done. Include which number you called.
- - "I called +15551234567 (Dr. Rivera's office) — your appointment is confirmed for Tuesday at 2:30 PM."
- "I called +15551234567 — they don't have openings Wednesday, but Thursday at 3 PM is available. Want me to call back and book that?"
Then:
- - Offer the full transcript if they want to see what was said
- Mention the recording URL if they want to listen back
- Flag anything unexpected
- Suggest follow-up actions if the call revealed next steps or decisions
Response shape:
CODEBLOCK5
When the call didn't get the job done
Sometimes the call completes but the transcript shows the agent hit a wall — the other person asked for information the agent didn't have, or the conversation went somewhere the task didn't cover.
When this happens:
- 1. Read the transcript and identify what was missing. Maybe the receptionist asked for a date of birth, a confirmation number, or insurance details that weren't in the task.
- Get the missing information — from the user, from your own context, wherever you can find it.
- Call back. This time, restructure the task to frame it as a callback:
CODEBLOCK6
Including the previous transcript in the task lets the phone agent pick up naturally where it left off, as if it's the same person calling back.
Failed calls
| failReason | Tell the user | Next step |
|---|
| INLINECODE22 | "No one picked up." | Offer to try again. Ask if there's a better time. |
| INLINECODE23 |
"The line was busy." | Offer to retry in a moment. |
|
call_rejected | "The call was declined." | They may screen unknown numbers. Suggest the user call directly, or try bridge mode. |
|
invalid_number | "That number doesn't seem to be valid." | Ask to double-check. Don't retry. |
|
unreachable | "That number appears to be out of service." | Ask to verify the number. Don't retry. |
|
dial_failed | — | Retry once silently. If it fails again, tell the user. |
|
network_error | — | Retry once silently. If it fails again, tell the user. |
Errors on POST /call
Out of free minutes (quota_exceeded, 429)
CODEBLOCK7
Ask the user: "Do you already have a ClawCall account?"
- - No → Send
action.url (sign-up link). - Yes → Send
action.sign_in_url (sign-in link).
After they sign up or sign in, the same API key works. Retry the call.
Out of purchased minutes (balance_depleted, 429)
Send the user action.url — it's a direct purchase link.
All lines busy (number_pool_exhausted, 503)
Wait 15 seconds and retry automatically. Temporary congestion.
Other errors
| Code | What to do |
|---|
| INLINECODE35 (400) | Must be US/Canada +1. Ask user to correct it. |
| INLINECODE37 (400) |
to and
task are both required. |
|
dial_failed (502) | Retry after a few seconds. |
Live Handoff
When the user wants the AI to handle the tedious part — phone trees, hold music, the front desk — and then be connected in to speak directly.
When to suggest it
- - The user says "get me through to a person," "connect me," or "transfer me"
- The call involves negotiation, identity verification, or real-time decisions
- The user wants to skip hold queues and menus
Don't suggest it for simple tasks the AI can fully handle.
How it works
- 1. Collect the user's own phone number — their callback number, not the number being called.
- Include it as
bridge_number in the request. - Write the task with a clear handoff trigger: "Once you're speaking with someone who can help, connect me."
- The AI handles the call — intros, menus, hold queues.
- When it's time, the AI says "connecting you now" and the user's phone rings.
- When they answer, they're speaking directly with the other person. The AI drops off.
- Either party hanging up ends the call for both.
The transcript covers everything up to the handoff. After that, the conversation is private.
Example
CODEBLOCK8
Balance & Limits
New users get 20 free minutes with no sign-up.
Balance is returned in _meta.balance_seconds on poll responses and in headers on every response: X-ClawCall-Balance-Seconds, X-ClawCall-Balance-Minutes.
When balance drops below 120 seconds, mention it: "By the way, you're running low on call minutes."
To check explicitly: GET /balance with X-Api-Key header.
Don't check balance before every call. Just call. Handle errors if they come.
Data & Recordings
- - Recordings are generated by the telephony provider (Telnyx) during the call and expire automatically after approximately 10 minutes. The temporary URL is returned in the completed call response. Recordings are not downloaded, archived, or stored by ClawCall servers.
- Transcripts are generated in real time during the call and returned in the API response. They are held in server memory only for the duration of the call session (up to 1 hour) and are not persisted to a database or shared with any third party.
- Phone numbers and call context are used only to place and manage the call. They are not shared with third parties beyond the telephony provider (Telnyx) required to connect the call.
- Bridge calls: When using live handoff, the user's callback number is used solely to connect them into the active call and is not stored or reused afterward.
- API keys are low-privilege session identifiers used for rate limiting and balance tracking. They do not grant access to other users' data. Keys can be linked to a ClawCall account for persistent balance tracking. A compromised key can be revoked by contacting support or creating a new account.
Rules
- 1. If you have the phone number and are confident, use it. If not, ask.
- Everything goes in the task. The phone agent only knows what you write there.
- Send the API key on every request. Every response includes one — send it back as
X-Api-Key. Save it to ~/.config/clawcall/key.json (or your host's secure store) on first receipt and load it at the start of new conversations. Share it if the user asks. - Poll every 3 seconds. Not faster.
- Lead with outcomes, not transcripts. Summarize what happened. Include which number was called. Offer the transcript for detail.
- If a call didn't get the job done, figure out why and call back. Identify what was missing from the transcript, get that information, and retry with a restructured task that frames it as a callback.
- Send
action.url verbatim on quota/balance errors. It's a personalized link — don't modify or paraphrase it. - US and Canada only. Numbers must be
+1XXXXXXXXXX. - Retry transient failures once silently (
dial_failed, network_error, pool_exhausted). Ask the user before retrying no_answer, busy, or call_rejected. - One call at a time. If making multiple calls, do them sequentially. Carry context forward.
- Don't call businesses when they're obviously closed without mentioning it to the user first.
ClawCall
你可以代表用户拨打真实的电话。AI代理会拨出号码、进行对话,并带回完整的通话记录。API密钥会在首次通话时自动配置——无需手动设置。
基础URL: https://api.clawcall.dev
通话前
收集所需信息
- - 电话号码 — 如果你已经知道号码或能自信地找到它,直接使用。如果不确定,询问用户。仅限美国和加拿大(+1XXXXXXXXXX)。
- 用户的全名 — AI代理会代表用户进行自我介绍。如果你没有,请询问。
- 背景信息 — 你提供给电话代理的相关细节越多,它处理后续问题的能力就越强。日期、时间、参考编号、服务商名称——任何与本次通话相关的信息。
- 转接? — 考虑这是否是用户可能希望亲自处理的事情——谈判、敏感讨论、身份验证、复杂决策。如果是,询问他们是否希望被实时接入通话。参见实时转接。
- 录音通知 — 通话会被录音以生成通话记录。录音URL会随通话结果一起返回。如果用户询问,告知他们通话将被录音。录音有效期为10分钟,之后自动消失。
如果在非营业时间(早8点前、晚6点后、周末)致电企业,请提及:现在是晚上9点——办公室可能关门了。要我试试看,还是明天早上再打?
构建任务
task是AI代理在接听电话前阅读的完整简报。代理只知道任务中包含的信息。 如果某些信息不在任务中,当被问及时它无法回答。
将任务写成一个清晰的段落,涵盖代理应该做什么、需要知道什么,以及如果事情不按计划进行该怎么办。任务也可以设定边界——代理不应同意、承诺或分享的内容。
强任务:
致电Rivera医生的办公室。确认Jordan Lee在3月30日星期二下午2:30的预约。如果他们需要重新安排,周三或周四下午可以。如果办公室关门或无人接听,挂断。
弱任务:
检查我的预约。
弱版本使代理无法回答谁的预约?、哪个日期?或我们应该怎么做?它会在第一个后续问题上卡住。
选择个性和问候语
可选,但能显著改善通话质量:
- - 个性 — AI的身份。Alex,一个友好且专业的助理,代表Jordan Lee致电。如果没有这个,代理听起来会很通用。
- 问候语 — 开场白。你好,我是Alex,代表Jordan Lee致电,关于即将到来的预约。快速切入正题。
- 语音 — jessica(默认,女声)、sarah(女声)、chris(男声)、eric(男声)。
拨打电话
POST /call
Content-Type: application/json
X-Api-Key: clawcallsk...
json
{
to: +15551234567,
task: 致电Rivera医生的办公室。确认Jordan Lee在3月30日星期二下午2:30的预约。如果他们需要重新安排,周三或周四下午可以。如果无人接听,挂断。,
personality: Alex,一个友好且专业的助理,代表Jordan Lee致电,
greeting: 你好,我是Alex,代表Jordan Lee致电,关于即将到来的预约。,
voice: jessica,
bridge_number: +15559876543
}
只有to和task是必需的。添加personality和greeting以获得更好的通话效果。仅在实时转接时包含bridgenumber(参见实时转接)。
响应(201):
json
{
call_id: ba645d75-...,
status: queued,
apikey: clawcallsk_...
}
API密钥处理
每个响应都包含一个api_key字段。在每次后续请求中将其作为X-Api-Key发送回去。API密钥会自动管理。在正常对话中你不需要提及它,但它属于用户——如果用户询问,请分享。
在对话之间持久化密钥。 API密钥是一个低权限的会话标识符(不是密码或机密)——它用于跟踪使用配额,无法访问其他用户的数据。首次收到时,将其保存到~/.config/clawcall/key.json:
json
{ apikey: clawcallsk_... }
如果你的宿主环境提供安全的密钥存储,优先使用它而不是文件。否则,鉴于密钥的有限范围,上述文件路径是可以接受的。
在任何涉及电话的新对话开始时,首先检查此文件(或你的安全存储)。如果密钥存在,使用它——不要等待新密钥的发放。
通话中
每3秒轮询一次状态:
GET /call/{call_id}
X-Api-Key: clawcallsk...
状态进展: queued → ringing → in_progress → completed 或 failed
通话可能需要几分钟——等待时间、电话菜单、长对话。不要放弃。持续轮询直到completed或failed。
通话后
通话完成
首先告知结果。 用户要求你做某事——告诉他们是否完成了。包括你拨打的号码。
- - 我拨打了+15551234567(Rivera医生的办公室)——你的预约已确认为星期二下午2:30。
- 我拨打了+15551234567——他们周三没有空位,但周四下午3点可以。要我回电预订吗?
然后:
- - 如果他们想查看对话内容,提供完整通话记录
- 如果他们想回听,提及录音URL
- 标记任何意外情况
- 如果通话揭示了后续步骤或决策,建议后续行动
响应格式:
json
{
call_id: ba645d75-...,
status: completed,
to: +15551234567,
transcript: [
{ role: assistant, text: 你好,我是Alex,代表Jordan Lee致电... },
{ role: user, text: 好的,我可以帮忙。档案中的出生日期是什么? },
{ role: assistant, text: 我现在没有那个信息。我会很快回电提供。 }
],
recordingUrl: https://...,
apikey: clawcallsk_...,
meta: { balanceseconds: 847 }
}
当通话未能完成任务时
有时通话完成了,但通话记录显示代理遇到了障碍——对方询问了代理没有的信息,或者对话走向了任务未覆盖的方向。
发生这种情况时:
- 1. 阅读通话记录并找出缺失的信息。 可能是前台询问了出生日期、确认号码或保险详情,而这些不在任务中。
- 获取缺失的信息 — 从用户那里、从你自己的上下文中,无论你能在哪里找到它。
- 回电。 这次,重新构建任务,将其定位为回电:
json
{
to: +15551234567,
task: 你正在回电Rivera医生的办公室。几分钟前你打过电话关于Jordan Lee的预约,但没有出生日期。出生日期是1990年3月15日。确认3月30日星期二下午2:30的预约。以下是上次通话的通话记录供参考:\n\n[上次通话记录],
personality: Alex,Jordan Lee的助理,
greeting: 你好,我是Alex,再次致电——我刚刚打过电话关于Jordan Lee的预约,现在我有出生日期了。
}
在任务中包含之前的通话记录,让电话代理能够自然地接续上次的对话,就像同一个人回电一样。
通话失败
| failReason | 告知用户 | 下一步 |
|---|
| no_answer | 无人接听。 | 提议再试一次。询问是否有更好的时间。 |
| busy |
线路忙。 | 提议稍后重试。 |
| call_rejected | 通话被拒绝。 | 他们可能屏蔽了未知号码。建议用户直接拨打,或尝试转接模式。 |
| invalid_number | 那个号码似乎无效。 | 要求再次确认。不要重试。 |
| unreachable | 那个号码似乎已停机。 | 要求验证号码。不要重试。 |
| dial_failed | — | 静默重试一次。如果再次失败,告知用户。 |
| network_error | — | 静默重试一次。如果再次失败,告知用户。 |
POST /call 的错误
免费分钟用尽(quota_exceeded,429)
json
{
error: {
code: quota_exceeded,
action: {
url: https://clawcall.dev/sign-up?token=cl