Overview
ClawCall places real phone calls for you. Send a US number and a structured request, and it dials, works through phone menus, waits on hold, talks with whoever answers, and reports back. There are three ways in. Each one places the same calls, under the same account, plan, and limits.
Remote MCP
For ChatGPT, Claude, and other AI hosts that support remote MCP with OAuth. In ChatGPT, install the official ClawCall plugin from ChatGPT's plugin directory. You sign in once. The host never sees an API key.
Set up ChatGPT →REST API
For your own code. One request starts a call. You poll until it finishes, then read the result.
Start the quickstart →Agent skill
For skill-aware agents such as Claude Code, Cursor, and OpenClaw. The skill drives the REST API for you.
Install the skill →
How a call works
- You start a call with a destination and a structured request. ClawCall returns a
call_idright away. - ClawCall makes the call. It navigates menus, waits on hold, and talks with the person who answers. It says it is an AI if asked.
- You poll
GET /call/. The:id lifecyclefield moves throughqueued,dialing,answered, andfinalized. - You read the result.
outcomesays what happened on the phone network. Thetranscriptfield holds captured transcript evidence when present, which is how you judge whether the task got done.
Quickstart
Place a call and read the result in four steps. You need curl, a US number you can answer, and jq for the polling loop.
Get an API key
Sign in and create a key under Dashboard → API keys. Keys start with
clawcall_sk_. To try ClawCall without an account, skip this step: your first call without a key starts the free trial and returns a new key in theapi_keyfield. Save it and send it on every request after that.Start a call
Send the destination and structured request as JSON. Replace
+14155550123with a number you control for your first test. Include every fact, detail, and question the recipient might need. Put commitments in authority, reference details in facts, and all questions in questions.The response comes back as soon as the call is queued. It is not the result of the call.
Poll until the call is finalized
Save the
call_idasCALL_IDand check it every 3 seconds. The call is over whenlifecycleisfinalized.Read the result
outcometells you whether the phone network connected the call. It does not tell you whether the restaurant booked the table. For that, check the nullabletranscript, which holds captured transcript evidence when present.Every field is described in The call object.
Authentication
Send your key in the X-Api-Key header on every request. Keep it on a server. Never put it in a browser bundle, a public repository, or a prompt someone else can read.
| Key | How it works |
|---|---|
| Account key | Created in the dashboard, or a trial key you linked. Uses your account's plan or trial and unlocks account endpoints such as /me/ and /me/. |
| Trial key | Issued automatically by your first POST /call without a key, in the api_key field and the X-ClawCall-Api-Key header. It draws on a free trial tracked by the network address that created it. |
Keep a trial key when you sign up
Open https:// with your trial key, or /sign-in? if you already have an account. ClawCall links the key to your account, so the same key now uses your plan. When a trial runs out, the trial_exhausted error carries this link in action.sign_in_url.
Manage keys in the dashboard. An unknown or revoked key is treated as no key at all. Account endpoints such as /me/ then return 401 auth_required. POST /call falls back to the trial key already issued to your network address, and returns 401 invalid_api_key only when there is none. Remote MCP does not use API keys at all: the AI host gets revocable OAuth tokens instead.
Place a call
POST /call starts one outbound call. Send a JSON body with a Content-Type: application/ header. Required fields are to, recipient, on_behalf_of, goal, and authority.allow. Include all known facts and questions; more information makes calls better. Objects are strict and cannot mix structured and legacy fields. The 100 KB JSON body limit is the only size cap.
| Field | Description |
|---|---|
tostring Required | US E.164 destination, such as +14155550123, without spaces. |
recipientstring Required | Business, department, location, or person expected to answer. |
on_behalf_ofstring Required | Person or organization represented; this grants no account access. |
goalstring Required | The full outcome wanted from this call. |
authorityobject Required | Required allow list of permitted commitments; [] means ask and relay only. Optional limits lists budgets, times, and other boundaries. |
factsarray | Every known detail as {label, value} strings, including callback numbers, account references, known menu paths, and prior-call results. |
questionsstring[] | Every question the user wants answered, including alternatives and follow-up details. |
handoffobject | Presence enables loop-in. The assistant rings your loop-in contacts, or your verified account phone when none are set. Optional handoff.when adds your trigger; requests for the user or a real person also trigger it. warm_greeting overrides the saved setting. |
voicemailobject | Use {kind: "end"} (default) to end the call without leaving a message (the recording notice at pickup still plays), or {kind: "leave_message", message: "..."} with only the words to convey, including authorized callback details. The agent leaves this message on the voicemail, so write it as the message itself, with exact names, numbers, and dates. Put no instructions to the agent inside message. |
assistant_namestring | A plain assistant name, such as Alex. |
voicestring | eric, jessica, sarah, or chris. Omission uses the saved voice. |
Optional lists must be non-empty when supplied, except authority.allow, which may be empty. Existing to plus task requests still work with legacy validation and settings. Send one format per request.
Response
201 Created with call_id, status: "queued", and a message. A trial call made without a key also returns api_key. Account responses carry X-ClawCall-Balance-Seconds, X-ClawCall-Balance-Minutes, and X-ClawCall-Tier headers. On unlimited plans the balance headers read unlimited.
End a call
POST /call/ stops a queued or live call. It is safe to repeat: a call that already ended returns success: true with the message Call already ended.
The call object
GET /call/ returns the call. You can read calls placed by your account, and calls placed from the same network address. Trial calls have no account, so they are matched only by the network address that placed them. Another account’s call returns 403 not_authorized, and an unknown ID returns 404 not_found. POST /call/ follows the same rules.
Lifecycle
| Value | Meaning |
|---|---|
queued | Accepted and waiting for a line. |
dialing | Ringing the destination. |
answered | Connected. The conversation is in progress. |
finalized | Over. The terminal fields below are now present. |
Fields
| Field | Description |
|---|---|
idstring | The call ID, the same value as call_id. |
directionstring | outbound or inbound. |
handling_modestring | agent for calls the AI handled. Inbound passthrough calls read passthrough. |
requestobject | For structured calls, the exact submitted request in GET /call/:id and /me/calls. Customer webhooks omit it, like task; fetch GET /call/:id. |
taskstring | The task text the phone agent received: the structured request written out, or the original legacy task. |
voice, personality, greetingstring or null | The effective voice; personality and greeting are null for structured calls. |
numbersobject | to, from (the caller ID used), and bridge_from (the line used for a handoff, or null). |
timestampsobject | queued_at, dialing_at, answered_at, finalized_at. Each is an ISO time or null. |
transcriptarray or null | Turns of { role, text, timestamp, phase? }. Null until the first turn. It grows while the call runs, so you can show progress. role names the speaker, such as assistant for ClawCall and user for the other party. phase marks turns from a handoff. |
outcomestring | Finalized only. The phone-network result. See the table below. |
outcome_detailobject | Finalized only. reason has code, title, message, and retryable. Show reason.message to people and use reason.retryable to decide on a retry. The carrier fields provider_error_code, hangup_cause, sip_hangup_cause, and hangup_source are nullable. |
talk_secondsnumber or null | Finalized only. Seconds from answer to hang-up. Null if nobody answered. |
recording_urlstring or null | Finalized only. A temporary recording URL when available. See Recordings. |
_metaobject | Finalized only. Your remaining trial or plan. balance_seconds: null with unlimited: true means an unlimited plan, not zero. |
Example
Outcomes
outcome is one of ten values. A network outcome does not prove task success: answered only means someone or something picked up. Voicemail is not an outcome. For structured calls, ClawCall leaves a voicemail only with voicemail.kind set to leave_message, and you learn that from the transcript.
| Value | Meaning |
|---|---|
answered | The call connected. Whether the task got done is in the transcript evidence actually captured. |
no_answer | Nobody picked up before the ring timeout. |
busy | The line was busy. |
rejected | The other side declined the call. |
invalid_number | The number is not in service or does not exist. |
unreachable | The number exists but could not be reached right now. |
network_error | A carrier network problem. Usually worth one retry. |
cancelled | You or your agent ended the call before it finished. |
system_error | ClawCall hit an internal error during the call. |
failed | The call failed for another reason. Check outcome_detail. |
List recent calls
GET /me/ lists your account’s calls. It needs an account key. Inbound history also needs Unlimited Reserve Plus and an active reserved number, or a number on your own Twilio account connected to ClawCall.
| Parameter | Description |
|---|---|
limitinteger | Default 25. Values above 200 are capped at 200. |
directionstring | outbound or inbound. |
sinceISO time | Only calls that ended at or after this time. |
- Calls are newest first. With
sinceordirection=, only finalized calls are listed, ordered by when they ended.inbound - The response is
{ calls, recordingWindowMinutes }. Each row is a call object without_meta, so it carries captured transcript evidence when present. - Rows add
recording_available_untilandrecording_expired. Hererecording_urlturns null once the 10-minute window closes. - An invalid parameter returns
400 invalid_query.
Live handoff
Include handoff when you may need to talk yourself, for example once a claims agent is on the line. The agent gets a tool to bring you in. It does not dial you right away.
- The agent decides it is time. It puts the other party on hold and calls your verified account phone on a separate line, or your loop-in contacts in order when you have them.
- You get a private briefing about who is waiting and why, and it asks whether you want to join. With
handoff.warm_greeting: falseit skips the briefing and connects as soon as your phone answers, so a voicemail or screening service could pick up instead. - You join or decline. If you join, both lines are bridged and the agent drops off. If you decline or miss the call, the agent goes back to the original call and can pass on your message.
| Value | Destination |
|---|---|
{} | Your loop-in contacts, or your verified account phone when none are set. Optional handoff.when adds a trigger; warm_greeting controls the private briefing, and each loop-in contact uses its own. |
| omitted | Loop-in is disabled. |
After you join, recording and transcription follow your Record bridged conversations setting (post_bridge_capture), so captured evidence may end at the bridge. Loop-in errors return before any call is placed: invalid_call_request (400 for malformed handoff), account_phone_unavailable (422, no single verified phone), account_phone_lookup_unavailable (503, try again shortly), and invalid_loop_in_destination (400, your phone is the destination or a ClawCall number).
In the dashboard assistant, ask for it in plain words, such as "Join me when a human is ready."
Recordings
A finalized call can include recording_url, a temporary recording URL when available. GET /call/ redirects (302) to the same temporary URL, or returns 404 recording_not_available when the call has none. On this route, a call you cannot access also returns 404 not_found rather than 403, so it never reveals that someone else’s call exists.
In /me/, recording_available_until marks the end of the 10-minute window and recording_expired turns true once it passes.
Call settings
Saved settings apply to every call that does not override them. GET, PUT, and DELETE /me/ need an account key.
| Field | Description |
|---|---|
voicestring | jessica, sarah, chris, or eric. Other values return 400 invalid_preferences. |
personalitystring or null | Used for legacy and inbound calls only; structured calls use assistant_name. |
greetingstring or null | The opening line for legacy outbound calls; ignored for structured calls. |
warm_greetingboolean | The loop-in briefing, for both directions. Starts as true. |
post_bridge_captureboolean | Record bridged conversations. Keeps recording and transcribing after you join. Starts as true. |
inboundobject or null | The inbound assistant. Null unless you have Unlimited Reserve Plus and an active reserved number, or a number on your own Twilio account connected to ClawCall. |
Reserved numbers and inbound calls
A reserved number gives your account a private caller ID for outbound calls. Choose one under Dashboard → Numbers. If your plan includes a reserved number but none is active, the call fails with 409 reserved_number_unavailable instead of switching to a shared caller ID. A reserved number handles one call at a time, so a second call returns 409 reserved_number_busy.
Unlimited Reserve Plus numbers can also receive inbound calls. ClawCall answers first as your assistant using your inbound profile. Configure instructions, voice, personality, and optional account-based loop-in from the dashboard or API. An inbound block can carry instructions, greeting, loop_in_user, passthrough_numbers, and knowledge_base, up to 20,000 characters of facts the assistant can tell callers. Each omitted field keeps its saved value, and a null knowledge_base clears it. On the first save, an omitted instructions or greeting takes the default text. Sending loop_in_user replaces a legacy handoff_number. The saved profile greeting does not replace or append to the fixed recording-disclosure opening.
passthrough_numbers lists up to 100 US callers who ring your verified phone directly with their own caller ID, skipping the assistant and the recording. An empty array clears the list and omitting it keeps the saved list. Send inbound: null to remove the inbound profile.
Webhooks
Instead of polling, ClawCall can send a signed POST to your HTTPS endpoint when a call starts or ends. Events are notifications: fetch the transcript and recording from the API paths in data.links. Each account has one endpoint and one signing secret. Set them on the Webhooks page or with an account key. If the API answers 404 webhooks_unavailable, webhooks are not turned on yet, so keep polling.
| Event | Sent when |
|---|---|
call.started | An inbound call comes in. data.call.numbers.from is the caller. |
call.completed | Any call, inbound or outbound, has ended, usually within 10 seconds of hang-up. On an answered call it waits up to 30 seconds for the recording, then adds data.links.recording; fetch it right away, because GET /call/ redirects to a link that expires about 10 minutes after the call ends. Fetch the transcript, when present, from GET /call/. It carries data.summary, a short AI summary, and data.caller, the other party's stated name and reason (a field is null when it wasn't said). Both are null when nobody spoke or no summary could be made. |
data.call has the fields of the call object without the transcript, task, voice settings, or recording_url. data.links paths are relative to https://. Outbound calls send no call.started, so match call.completed to the call_id that POST /call gave you. Only calls made after you first set the endpoint are sent.
Verify each request
Requests follow the Standard Webhooks format, so its libraries can verify them. webhook-signature is v1, plus a base64 HMAC-SHA256 of {webhook-id}.{webhook-timestamp}.{body}, keyed with the decoded part of the secret after whsec_. Check it against the raw body and reject timestamps more than 5 minutes old.
Custom headers
To check a credential of your own, such as an Authorization header, add up to 5 custom headers. ClawCall sends them with every delivery and test event, stores the values encrypted, and only shows a masked value_preview afterwards. ClawCall's own Content-Type, User-Agent, and webhook-* headers always win, and names like Host or Content-Length are refused. Moving the endpoint to another origin (scheme, host, or port) removes the saved headers, so a credential never follows it to another host.
Delivery and retries
- Answer with any 2xx within 10 seconds. Anything else is retried after 30 s, 2 min, 10 min, 30 min, 1 h, 2 h, 4 h, and 6 h.
410 Gonestops retries for that event. - Retries keep the same
id, so deduplicate on it. For an inbound call,call.completedwaits untilcall.startedis delivered or given up. - The endpoint must resolve to a public internet address. Redirects are not followed.
Set up with the API
| Request | Effect |
|---|---|
GET /me/ | The endpoint, secret, events, masked custom headers, and headers_available, or null. |
PUT /me/ | Sets or changes the URL. The first save creates the secret; changing the URL keeps it. An optional headers object replaces every custom header. |
PUT /me/ | Adds one custom header or replaces it. Body: { "value": "..." }. |
DELETE /me/ | Removes one custom header. |
DELETE /me/ | Removes the endpoint, secret, and custom headers. |
POST /me/ | Replaces the secret. The old one stops working immediately. |
POST /me/ | Sends a signed webhook.test event and returns your endpoint's answer. |
GET /me/ | Recent calls with each event's status, attempts, and last error. |
POST /me/ | Sends one event again. Body: { "event": "call.completed" }. |
Errors
Errors share one envelope: a stable code, a readable message, and sometimes a reason, an action, and a quota. When an action.url is present, send people there exactly as returned. It is personalized.
| Code | What to do |
|---|---|
missing_fields400 | Send to, recipient, on_behalf_of, goal, and authority.allow. |
invalid_phone400 | Use a US number in +1XXXXXXXXXX form. The area code cannot start with 0 or 1. |
unsupported_destination400 | ClawCall only calls US numbers today. |
invalid_call_request400 | Fix the field identified in the error. Required strings must be non-empty and nested objects are strict. For REST, a non-empty string task selects legacy behavior; extra keys, including structured fields, are ignored and their names are logged. A blank or whitespace-only task is omitted when structured fields are present. MCP rejects task alongside any structured-only field. |
invalid_loop_in_user400 | Legacy/inbound flags must be boolean. Structured handoff validation uses invalid_call_request. |
auth_required401 | This endpoint needs an account key. Follow action.url to sign up. |
invalid_api_key401 | POST /call only: the key is unknown and this network address has no trial key. Replace the key, or send the request without one to start a trial. |
trial_exhausted402 | The trial is used up. Send the user to action.url, or action.sign_in_url if they already have an account. |
plan_required402 | The account has no active plan or trial left. Follow action.url. |
phone_verification_required403 | A dashboard sign-in must verify a phone first. Follow action.url. |
not_authorized403 | The call exists but belongs to another account or network address. |
not_found404 | No call or route with that ID. |
reserved_number_busy409 | Your reserved number is already on a call. Retry when it ends. |
concurrent_call_limit409 | Your account already has a call in progress on a shared line. No new call was placed. Wait for it to finalize before placing the next call. Never retry in a loop. |
reserved_number_unavailable409 | Your plan includes a reserved number but none is active. No shared caller ID is substituted. |
call_request_rejected422 | The safety check declined this request. No call was placed. See message and action.description. |
account_phone_unavailable422 | Loop-in needs one verified phone on the account. |
dial_failed502 | The carrier refused the dial. Retry once if action.type is retry. |
number_pool_exhausted503 | Every outbound line is busy. Wait about 15 seconds and retry once. |
call_screening_unavailable503 | The safety check is briefly unavailable. No call was placed. Retry shortly. |
Retry automatically only when the error says it is temporary: action.type is retry. Never retry a call that may already be running just because a request timed out. Poll it instead.
What are the limits and how much does it cost?
| Plan | What you get |
|---|---|
| Free trial$0 | 30 calls and 30 minutes, whichever lasts later. No card. |
| Unlimited$4.99/month | Unlimited calls from shared ClawCall numbers. |
| Unlimited Reserve$8.99/month | Adds one private reserved caller-ID number for outbound calls. |
| Unlimited Reserve Plus$14.99/month | Adds AI inbound answering on the active reserved number. |
The free trial includes 30 calls and 30 minutes, whichever lasts later. A trial call counts only when it finalizes with at least 5 seconds of talk time, so failed dials and very short calls do not use one. Signed-in accounts track the trial per account and trial keys track it per network address. See pricing for the full comparison.
Check your balance
GET /balance returns tier, balance_seconds, balance_minutes, low_balance, and a plan or trial object. Legacy prepaid balances have neither and report numeric seconds. On an unlimited plan unlimited is true and both balance fields are null. Never read null as zero. A trial stays usable while trial.allowed is true, even at zero seconds, as long as calls remain.
Limits
- Calls go to US +1 numbers only, and the agent speaks English only.
- Trial and Unlimited accounts place one outbound call at a time on shared lines. A second call while one is running returns
409 concurrent_call_limit. Wait for the current call to finalize before placing the next. Anonymous callers share this limit per IP address. - If all shared lines are busy with other accounts, the call does not start.
POST /callreturns503 number_pool_exhausted, and you retry shortly. - Unlimited Reserve and Reserve Plus calls always use your reserved number, one call at a time. A new call while that number is on a call returns
409 reserved_number_busy. - On shared-pool calls, looping you in uses a second shared line while you are connected.
- ClawCall does not hold HIPAA, PCI, or SOC 2 attestation today.
- Never ask a call recipient for the recipient's own card details, SSN or other government ID, passwords, one-time codes or health information. You may give the user's own details to a business or agency for the user's errand, including date of birth, address, account or member numbers, insurance IDs, health details and PINs. You may request the user's own records. This includes acting for a family member the user manages errands for.
- For passwords, live one-time codes and full payment-card numbers, prefer loop-in or a private consult so the value is spoken live instead of written into the request, where it would be stored. Loop-in does not promise that recording or transcription stops.
Remote MCP
ChatGPT, Claude, and other hosts that support remote Streamable HTTP MCP with OAuth can use ClawCall directly. In ChatGPT, install the official ClawCall plugin, listed in ChatGPT's plugin directory: select Plugins, search “ClawCall”, select Install plugin, then Allow connection. ChatGPT needs no Developer mode, pasted URL, or OAuth configuration, and OpenAI dots use the same plugin. In other hosts, add the endpoint below. Then sign in to ClawCall and approve the calls:read and calls:write scopes. The host receives revocable OAuth tokens, not your API key.
Developers can still add the endpoint to ChatGPT by hand through Developer mode, but the plugin directory is the ChatGPT path for everyone else.
Remote MCP endpoint
https:// api.clawcall.dev/ mcpStateless Streamable HTTP on MCP revision 2026-07-28, with legacy negotiation for 2025-era clients. Step-by-step setup for each host:
- Make phone calls from ChatGPT with the official ClawCall pluginChatGPT plugin directory
- Connect Google Gemini to ClawCall with remote MCPGemini Spark custom Connected App
- Connect Claude to ClawCall with remote MCPCustom connector
- Connect Microsoft Copilot to ClawCall with remote MCPCopilot Studio MCP onboarding wizard
- Connect Perplexity to ClawCall with remote MCPEnterprise custom remote connector
- Connect OpenAI Codex to ClawCall with remote MCPCLI or IDE MCP server
- Connect Cursor to ClawCall with remote MCPCustomize / mcp.json
- Connect Grok Build to ClawCall with remote MCPGrok Build CLI
- Meta AI and ClawCall: compatibility and fallbacksAnother app, or the API
- DeepSeek and ClawCall: compatibility and fallbacksAnother app, or the API
- Make phone calls from Grok Bot with ClawCallAsk your Bot in chat
- Make phone calls from OpenAI dots with the ClawCall pluginChatGPT plugin directory
OAuth discovery architecture
The host reads the authorization-server metadata and the RFC 9728 protected-resource metadata, registers itself with Dynamic Client Registration, and then runs the OAuth 2.1 authorization-code flow with PKCE S256. It receives tokens only for the scopes the user approves.
| Step | Endpoint |
|---|---|
| Discover | https://Authorization-server metadata: authorize, token, registration, and revocation endpoints, and PKCE S256. |
| Discover | https://RFC 9728 protected-resource metadata for the MCP endpoint and its scopes. |
| Authorize | https://Authorization-code flow. The user signs in to ClawCall and approves scopes. |
| Token | https://Exchanges the code (with the PKCE verifier) and refreshes tokens. |
| Register | https://Dynamic Client Registration for a public OAuth client. |
| Revoke | https://Revoke a token when the host disconnects. |
Scopes
| Scope | Allows |
|---|---|
calls:read | Read plan/trial state, call settings, reserved-number status, call status, captured transcript evidence when present, history, and temporary recording access when available. |
calls:write | Place and hang up real phone calls or update call settings when you ask the assistant to do so. |
The twelve tools
The host should call get_calling_guide with call_format: "structured" before any other ClawCall work. place_call_and_wait waits 45 seconds by default and up to 90. If the call is still running, keep polling get_call.
| Tool | What it does |
|---|---|
get_calling_guideRead | Returns current request fields, workflows, and example requests for building calls. |
get_balanceRead | Read the signed-in account's plan and remaining trial allowance. |
get_call_settingsRead | Read reusable voice/personality, reserved-number capabilities, and inbound-assistant availability. |
update_call_settingsWrite | Update global or inbound call settings in separate calls. |
place_callWrite | Start one real outbound phone call and return immediately. |
place_call_and_waitWrite | Start one call and wait up to 90 seconds for an initial result. |
get_callRead | Read a call's lifecycle, outcome, and the latest transcript lines when present. |
get_call_transcriptRead | Read the transcript evidence captured for a call. |
list_callsRead | Read recent call history for the connected account. |
get_recordingRead | Get a temporary, playable recording URL when one is available. |
hangup_callWrite | Stop a queued or live phone call. |
connect_webhookWrite | Send call events to an agent's webhook trigger, such as a Grok Bot routine, then send a test event. |
Verify, then disconnect when done
To test the connection without calling anyone, ask: "Check my ClawCall plan and remaining trial allowance. Do not place a call." The host should pick get_balance. Once connected, the host can choose ClawCall on its own for normal phone-call requests.
To disconnect, remove ClawCall in the host. Then open Dashboard → Settings → Connected AI assistants and choose Disconnect. Revoke happens there: ClawCall revokes that connection’s whole token family.
Agent skill
Skill-aware agents such as Claude Code, Cursor, and OpenClaw can install the ClawCall skill from ClawHub or GitHub. Before each operation the skill fetches the current guides from https://, so it follows API changes without a reinstall.
It uses CLAWCALL_API_KEY when set. Otherwise the first call starts a trial and the skill saves the issued key. Then ask in plain words:
Troubleshooting
- The call will not start
- Read
error.code. Most failures areinvalid_phone(use+1and 10 digits),missing_fields, or a used-up trial. For a JSON body, sendContent-Type: application/; without it the body is ignored and you getjson missing_fields. - The outcome is answered, but the task did not happen
answeredis a network result. Check the transcript evidence actually captured to see what was said, then place a follow-up call with additional facts and questions if needed.- The transcript is null
- Nobody has spoken yet, or the call never connected. Keep polling while
lifecycleis notfinalized. - The recording link expired
- Recording links are temporary and expire on the carrier’s side, and recordings are deleted 10 minutes after the call ends. Fetch the recording soon after the call finalizes.
- An API key stopped working
- It may have been revoked in the dashboard. Create a new key and update whatever sends the
X-Api-Keyheader. - The MCP host shows old or missing tools
- Refresh the connector’s tool list in the host. ClawCall exposes twelve tools.