Overview
An integration is a connection from your workspace to a service. You enter the service’s credentials once. 60db checks them with a live test, then stores them encrypted. You then attach the connection’s tools to an agent. During a call, the agent can use those tools. 60db runs each tool on its servers with your stored credentials. The caller does not see any of this. There are three kinds of connection:
The API reference starts at List integration catalog.
The catalog
The catalog lists 24 entries. Two are custom kinds: the Custom MCP Server and the Custom Webhook. The other 22 are providers. Each entry connects in one of three ways:- Key or token. You enter a key, token or account details. You can connect these now.
- Custom. You enter a URL. This applies to the Custom MCP Server and the Custom Webhook.
- Not connectable here. These entries cannot be connected with a key yet. Salesforce, Google Calendar and Google Drive need an app setup. Avaya uses a telephony guide. WhatsApp has its own feature.
The catalog endpoint returns each field with its
key, and the field key is what you send in fields.
Connect an integration
Send the provider key and the field values. Use the keys from the catalog.nameis optional. It defaults to the catalog name. Names are unique in the workspace, up to 64 characters.- A text value is up to 4,096 characters. Secret values are never returned. The response shows a hint of the last four characters.
- A field that is not in the catalog for that provider is refused.
- If the input is invalid, nothing is stored. The request fails with
400or422. - If the input is valid but the live test fails, the connection is stored with
status: "error"andlast_error. The request still returns201. Fix the fields and test again.
The live test
Every connect and every change runs a live test. Test integration runs it again on demand. The test has an 8 second limit.- Key providers. The provider’s own check runs with your credentials.
- Custom MCP server. 60db connects to the server and checks that it answers.
- Custom webhook. 60db sends a signed
pingto the URL of the first action. See The ping test.
status is connected after a passing test and error after a failing one. last_error holds a fixed message. The provider’s own error text is never shown.
Attach tools to an agent
Pick the tools an agent may use withintegration_tools on Create agent or Update agent. Each pick is a connection and a tool key:
name:
Limits:
- An agent has up to 16 tools in total. This counts its own
toolsand itsintegration_toolstogether. Over the limit returns422 TOO_MANY_TOOLS. - A tool name is up to 64 characters, with letters, digits and
_only. Two picks cannot give the same name. - An agent that uses only integration tools does not need a
tool_webhook_url. That URL is only for the agent’s owntools. - When you delete a connection, its tools are removed from every agent in the workspace. See Delete integration.
- When an update removes an action from a custom webhook, that action’s tool is removed from every agent that holds it, in the same change.
Connect integrations to agents
A connection’s tools reach an agent in one of two ways:- Per agent. Set
integration_toolson Create agent or Update agent. Use this when you are editing one agent. - Per connection. On the Integrations page, open a connection and use Connect to agents. The dialog lists the agents and the tools of the connection, and saves the choice. With the API, use Assign integration agents, which sets the agents of one connection in one request.
- Each agent you list gets exactly the tools you list for this connection. Its tools from other connections stay.
- An agent you leave out, or list with no tools, loses this connection’s tools.
- Every agent that changes is updated as an agent edit is, and synced to the voice runtime.
- The change is all or nothing. Every agent is checked first, so a refusal changes nothing.
used_by field of every connection, list the agents that hold the connection’s tools:
used_by is [] when no agent holds a tool of the connection. A connection that is just created is used by no agent.
When an update removes an action, the tool of that action is removed from every agent that holds it. Deleting a connection removes all its tools from every agent.
How tools run during a call
When the agent calls one of these tools, 60db does the following:- Loads the connection and its stored credentials.
- Checks the arguments against the tool’s parameters.
- Calls the provider, the MCP server, or your webhook.
- Caps the result at 16 KB and returns it to the agent.
tool_webhook_url.
A result larger than 16 KB is replaced with the first 2,000 characters of its JSON and a flag:
Each tool call is logged with its arguments, its outcome and its latency. See List tool events.
Custom MCP servers
A custom MCP server is an endpoint that speaks the MCP protocol. 60db connects to it with Streamable HTTP. Legacy HTTP+SSE servers are not supported.
60db lists the server’s tools when you ask for them. The list is cached for about a minute. Pick the tools you need in
integration_tools. A tool whose parameter schema is larger than 4 KB cannot be picked, and the pick returns 422 INTEGRATION_TOOL_INVALID.
Custom webhooks
A custom webhook is one connection to HTTPS endpoints that you run. The connection holds shared headers and one signing secret. It also holds one or more actions. Each action is a tool that the agent can call during a call: it has its own URL, method, description, JSON Schema parameters and fixed values. When the agent calls a tool, 60db sends a signed request to that action’s URL. Use this for your own functions, such as a booking system or a stock check.Create a webhook
signing_secret. Store it now. One secret signs the requests of every action in the connection. See Signing.
The agent sees two tools: webhook_booktable__book_table and webhook_booktable__check_availability. Each tool’s description is its action’s description, and its parameters are its action’s parameters. The runtime names are listed in Attach tools to an agent.
Fields
Connection fields:
Action fields:
Send
key on every action. The key is the tool’s identity. If you change a key, the agents that hold the old tool lose it. An action sent without a key gets one from its name, so renaming it can also change its key.
Single-action form. The flat fields url, method, description, parameters and body_template, without actions, still work. They describe one action with the key call, so its tool keeps the runtime name webhook__<name>. On a webhook with several actions the flat fields are refused. Send actions instead.
Parameters
parameters is a JSON Schema object with "type": "object". Each property must have one of these types: string, number, integer or boolean. Every name in required must be a listed property. Objects, arrays and nested schemas are not supported.
Choice lists
Astring property can list its allowed values with enum:
enumis allowed onstringproperties only. It has 1 to 50 values. Each value is a non-empty string of up to 200 characters, and no value repeats.- A value outside the list is refused before the request is sent. During a call, the agent receives
{ "error": "tool_unavailable", "reason": "bad_arguments", "message": "plan must be one of: basic, pro" }. A direct action returns422 INTEGRATION_BAD_ARGUMENTSwith the same message. - A property the agent leaves out is not checked against the list. Put it in
requiredto make it mandatory.
How a call is sent
POST, PUT and PATCH. 60db sends a JSON body. It is built in this order:
- The
body_templatevalues. - The arguments the agent chose. They replace a template value with the same key.
- A
_60dbobject with the connection, the tool name, and, during a live call, the call id and the agent id.
call_id and agent_id are present only during a live call. A call started with Run an action does not have them.
GET and DELETE. These methods have no body. The declared arguments are sent as the query string, for example ?date=2026-11-05&guests=4. Values that are objects are refused with bad_arguments. The body_template is not sent.
Your answer
Return a2xx status. 60db reads the answer like this:
A redirect is an error. 60db does not follow redirects. A non-
2xx status is an error, and the reason follows the table in How tools run during a call. Respond within the 6.5 second budget during a live call.
Signing
60db signs every request to your endpoint. Each request has three headers:raw is the body as sent. For POST, PUT and PATCH it is the JSON body. For GET and DELETE it is the query string exactly as sent, without the leading ?.
- The signing secret starts with
whsec_. It is shown once, in the create response. It is not shown again. It belongs to the connection, so one secret signs the requests of every action. - To get a new secret, use Rotate signing secret. The old secret stops working at once. Update your endpoint in the same moment.
- Changing the URL or the method keeps the signing secret.
Changing an endpoint
Changing a webhook’s destination drops its shared headers. The signing secret is kept. A change counts as a destination change when either of these is true:- An existing action’s URL or method changes. A change of path or query counts as well.
- An action is added, or moved, to an origin (scheme, host and port) that the connection did not use before the change.
headers again in the same request if your endpoint needs them, and check your endpoint after the change.
Verify signatures
Verify every request before you act on it. The rules match the other 60db webhooks: the secret is used as UTF-8 text, the raw bytes are used, timestamps more than 300 seconds from your server’s clock are refused, and the comparison is constant time. The examples below are complete. They use only standard libraries. Node.jsThe ping test
When you create a connection, or run Test integration, 60db sends this request to the URL of the first action. The ping is always aPOST, whatever method that action uses:
2xx status means the connection is connected. The body is not read. Any other status is an error, and the connection is stored with status: "error".
The create request sends the first ping before it returns the signing secret. So you do not have the secret yet when that ping arrives. An endpoint that verifies signatures refuses it, and the connection is stored with status: "error". Store the signing_secret from the response, then run Test integration. The new test passes when your endpoint answers 2xx.
Run an action with curl
You can run one action of a connection without a call. Use this to check a connection, or to run a step from your own code. The action runs the same way as during a call. It has the same argument checks and the same 16 KB result cap, with a 15 second budget.action must be one of the tools that List integration tools returns for the connection. For a custom webhook, action is the action’s key, for example book_table. Provider failures return 502 with a code that names the cause. Your own rate limit returns 429. See Run integration action for every status and code.
Limits and roles
API keys need the
agents scope.