Skip to main content
Use this when your client can dial only one WebSocket URL and give it a shared secret. Examples are a media application or a stream-to-WebSocket setting in a telephony platform, or your own app. Each connection places one call with the agent. You do not start a call first, and you do not get a one-time URL. The client dials the same URL for every call. The agent answers in its voice, uses its tools and knowledge base, and can press keys, transfer to a person or hang up, as in an Agent Stream WebSocket call. If your code can start calls, the two-step flow is still available. See Start a call from your code.

Quick start

  1. Get the agent’s media_websocket_url from Get agent. It looks like wss://api.60db.ai/ws/agents/{agentId}/media.
  2. Get the agent’s secret, the whsec_… value from Create agent (webhook_secret) or from Rotate webhook secret.
  3. Connect with one of the authentication options, then stream audio in the audio format you chose.

The URL

wss://api.60db.ai/ws/agents/{agentId}/media agentId is the agent’s id. The URL takes two optional query parameters:

The shared secret

The secret is the agent’s signing secret. It starts with whsec_, and it is shown only in the Create agent response and in the Rotate webhook secret response. Get agent does not return it.
  • Rotating the secret refuses the old one at once.
  • The same secret signs the requests that 60db sends to your server for this agent, so rotating it changes both at once. Update both places.
Each call runs with the permissions of the agent’s creator. If that person is no longer an active member of the workspace, or is no longer allowed to place calls, the connection is refused with 403. Removing the creator from the workspace therefore stops the URL from placing calls.

Authentication

Send one of these with the connection request. Any one of them is enough. Use the Bearer header when you can. If your platform signs requests, use the signed headers. Use the query option only as a last resort.

Node.js: Bearer

This needs the ws package (npm install ws). The global WebSocket cannot set headers.

Node.js: signed headers

Compute the signature just before you connect, because the timestamp must be within 300 seconds.

Audio

Send caller audio as binary messages in real time. The agent’s audio comes back as binary messages in the same format.

Raw audio without a start message

A client may send binary audio first and no start message. When the first frame is binary, 60db first creates the native start message {"event":"start","format":"<format from the query>"} and then passes the frame on. So the format query must match the audio you send. If the first frame is text, it is passed on unchanged. A native-style start message from the Agent Stream WebSocket therefore also works here.

Refusals

A refused connection gets a plain HTTP response instead of a WebSocket. A WebSocket client reports it as an unexpected server response with that status. The body is JSON: {"success": false, "message": "…"}. A 401 also sends WWW-Authenticate: Bearer. The message never contains the secret. The checks run in this order. The first failing check decides the status.

Messages and limits

After the connection opens, the messages are the same as on the Agent Stream WebSocket:
  • From the agent: started, clear, dtmf, transfer, hangup, ended and, when your start message carried a stream id, the platform’s end-call command (see End-call command).
  • From your client: stop, dtmf and transfer_result.
Limits:
  • A message over 4 KB closes the connection with 1009.
  • The server pings every 15 seconds. A connection silent for 45 seconds is closed with 1001.
  • A call lasts at most 1,020 seconds. The socket then closes with 1000.
  • If more than 64 KB arrives before the call service is ready, the socket closes with 1008.
  • If the call service fails, the socket closes with 1011.
Each accepted connection creates one call with the source websocket. It is billed like a stream call. You can end a running call from your server with End stream call. The call keeps the sentiment and judge scores from the runtime’s ended message. If the client leaves before the connection is accepted, the placed call is closed without connecting.

Settings for a media application form

Use these values in the form of a “media application” or “stream to WebSocket” setting: Check how your platform sends the shared secret. If it sends an Authorization: Bearer header, the Bearer option applies. If it signs requests with a timestamp, the signed headers option applies. If it only puts the secret in the URL, the query option applies, with the risk described in Authentication.

Start a call from your code

To start a call from your server and get a one-time URL instead, use Start stream call and follow the two steps in the Agent Stream WebSocket guide. That flow needs an API key on your server, and the URL it returns is valid for 55 seconds.