Quick start
- Get the agent’s
media_websocket_urlfrom Get agent. It looks likewss://api.60db.ai/ws/agents/{agentId}/media. - Get the agent’s secret, the
whsec_…value from Create agent (webhook_secret) or from Rotate webhook secret. - 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 withwhsec_, 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.
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 thews 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,endedand, when yourstartmessage carried a stream id, the platform’s end-callcommand(see End-call command). - From your client:
stop,dtmfandtransfer_result.
- 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.
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.