Overview
Agents talk to your server in two ways. Both are HTTPS endpoints that you set on the agent, and 60db signs every request.
Both use the same signing scheme. See Verify signatures.
Define tools
Add tools to an agent withtools. Each tool is described with JSON Schema, so the agent knows when to use it and what arguments to send.
Set the URL on the agent when you create it or later with
PATCH /agents/{agentId}. A URL that is not https:// returns 400 VALIDATION_ERROR. A URL on port other than 443, one with credentials or a fragment, or one that resolves to a private or loopback address returns 422 UNSAFE_WEBHOOK_URL.
Tool call request
When the agent calls a tool, 60db sends aPOST to your tool_webhook_url:
Your reply
Reply with a JSON object within about 6 seconds. The agent speaks what it needs from that object.2xx, the agent receives an error object instead of your reply. The call continues.
Other
reason values: unsafe_url (the address failed the safety check at call time).
Notes:
- No retries. A tool call is sent once. If it fails, the agent gets the error.
- Duplicate calls. If the same
tool_call_idarrives again, 60db returns the saved answer. Your endpoint is not called a second time. - Tool log. Every tool call is logged with its arguments, your reply, status code and latency. See the Tool log in the dashboard, or
GET /agents/{agentId}/tool-eventsfor the last 50. Logs are kept 30 days.
Example tool endpoint (Node.js)
Example tool endpoint (Python)
Call transfer
Besides webhook (JSON) tools, an agent can hand a call to a person. Settransfer_targets on the agent, or per call in overrides.transfer_targets:
How it works. The
name is what callers ask for (“connect me to Sales”), so use a team name callers would say, not “Call Transfer”. The numbers are tried in turn until someone answers. The first target is also used when a caller asks for “a person”. 60db adds the matching instruction to your agent automatically; you don’t need to write it in the script.- Each group becomes a function the agent can use,
transfer_to_<name>(Sales Teambecomestransfer_to_sales_team). The agent only picks a name; the numbers stay with you. - The first group is used when a caller asks for a person without saying which team.
- With several numbers in a group, they are tried in turn. If one fails or refuses, the next is tried, and the call stays with the agent if none answers.
- Up to 10 groups of up to 10 E.164 numbers. Names must be distinct, and webhook tools cannot be named
transfer_callor start withtransfer_to_. summary.transferredon the call says whether it was handed over. The transferred leg is billed as Dialer minutes on your line.
Events
When a call ends, or its recording is ready, 60db sends an event toevent_webhook_url.
Events are sent only when the agent has an
event_webhook_url. recording.ready is sent only for recorded calls. It can arrive after call.completed.
Envelope
Every event has the same envelope:recording.ready carries the recording details and transcript, not a download link:
https://api.60db.ai{audio_path} (add ?download=1 to save it as a file).
Event headers
Retries
- Any response other than
2xx, a timeout or a network error counts as a failed attempt. Redirects count as failures too. - Reply quickly. Acknowledge with
2xxbefore doing slow work. A reply slower than about 5 seconds counts as a timeout. - 60db makes up to 5 attempts. It waits 30 seconds, then 1, 2 and 4 minutes between them.
- After the fifth failed attempt the event is marked failed and is not sent again.
- Events can arrive more than once, for example if your response was lost. Process each
X-60db-Event-Idonce. - Events can arrive out of order. Read the call again with
GET /agents/calls/{callId}if you need its current state.
Verify signatures
Verify every tool call and event before you act on it.- Use the secret exactly as returned (
whsec_…). Use its UTF-8 bytes as the HMAC key. Do not decode it. - Hash the raw body bytes as received. Do not parse and re-serialise the JSON first.
- Reject timestamps more than 300 seconds from your server’s clock.
- Compare signatures in constant time.
Node.js
Use the SDK helper:Python
Use the SDK helper:Test with curl
curl cannot verify a signature, but you can send a signed test request to your endpoint:Rotate the secret
webhook_secret. The old secret stops working at once. This covers tool calls and events, including retries that have not been sent yet.
Update your server with the new secret right after you rotate. Until you do, signatures will not verify. To limit the gap, store the new value and redeploy in one step.
Related
- Agents: setup, call lifecycle, pricing and limits
- Get call and Get transcript
- List tool events
- Rotate webhook secret