Skip to main content

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.
Some rules apply to every connection:
  • name is 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 400 or 422.
  • If the input is valid but the live test fails, the connection is stored with status: "error" and last_error. The request still returns 201. Fix the fields and test again.
To change a connection, use Update integration. Send only the fields that change. A secret you leave out keeps its stored value. If you change a destination field, the stored secrets are dropped and you must send any required secret again. A custom webhook has no required secret, so its headers are dropped without an error. See Changing an endpoint.

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 ping to 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 with integration_tools on Create agent or Update agent. Each pick is a connection and a tool key:
List the tool keys for a connection with List integration tools. The agent sees each tool under a runtime name. The agent response shows this name as name: Limits:
  • An agent has up to 16 tools in total. This counts its own tools and its integration_tools together. Over the limit returns 422 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 own tools.
  • 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_tools on 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.
The per-connection request sets the answer exactly:
  • 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.
The answer, and the 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:
  1. Loads the connection and its stored credentials.
  2. Checks the arguments against the tool’s parameters.
  3. Calls the provider, the MCP server, or your webhook.
  4. Caps the result at 16 KB and returns it to the agent.
The tool call has a time budget of 6.5 seconds during a call. Answer quickly. The call is not forwarded to your tool_webhook_url. A result larger than 16 KB is replaced with the first 2,000 characters of its JSON and a flag:
When a tool fails, the agent gets an answer instead of an error, so the call continues:
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

The response includes 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.
The agent sends only the properties you declare. Any other key it invents is removed before the request leaves 60db. Empty values are left out.

Choice lists

A string property can list its allowed values with enum:
  • enum is allowed on string properties 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 returns 422 INTEGRATION_BAD_ARGUMENTS with the same message.
  • A property the agent leaves out is not checked against the list. Put it in required to make it mandatory.

How a call is sent

POST, PUT and PATCH. 60db sends a JSON body. It is built in this order:
  1. The body_template values.
  2. The arguments the agent chose. They replace a template value with the same key.
  3. A _60db object with the connection, the tool name, and, during a live call, the call id and the agent id.
For example, with the template above and a call at 19:30 for four guests, the body is:
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 a 2xx 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.
Changing an action’s description, parameters or body template is not a destination change, so the headers stay. The change is saved without an error. Send 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.js
Python (Flask)
Use the raw query string, not a rebuilt one. Re-encoding the query can change its bytes, and the signature would not match.

The 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 a POST, whatever method that action uses:
Any 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.