Server Messages
Server Messages
Each assistant can POST what happens during a call to its own server URL — call status, the end-of-call report, and tool calls. Configure it per assistant, so different assistants can talk to different backends.
Configure
Server messages are part of the assistant, so you set them with PATCH /agents/{id}: serverUrl (null turns them off), serverMessages (which types to send), and serverUrlSecret (optional signing key). This is delivery config rather than agent behaviour, so changing it never creates a new version and needs no publish.
curl -X PATCH https://api.bolchoai.in/v1/agents/{id} -H "Authorization: Bearer $BOLCHO_API_KEY" -H "Content-Type: application/json" \
-d '{
"serverUrl": "https://api.yourapp.com/bolcho/server",
"serverMessages": ["status-update", "end-of-call-report"],
"serverUrlSecret": "your-signing-secret"
}'Message types
status-update — the call started (status: "in-progress") or ended (status: "ended"). A call that fails arrives as an ended update with a telling endedReason, not a separate status. end-of-call-report — fires once after post-call analysis with the transcript, summary, outcome and cost breakdown. tool-calls — the agent invoked a tool; notification only, the response body is ignored (a tool's result comes from the tool's own config).
Payload
Every message POSTs { message: { type, timestamp, agent, … } }, with the type also in the x-voxa-message header so you can route without parsing the body.
{
"message": {
"type": "end-of-call-report",
"timestamp": "2026-07-17T10:32:11.402Z",
"agent": { "id": "…", "name": "Support Assistant" },
"call": {
"id": "…",
"direction": "inbound",
"status": "completed",
"durationSeconds": 84,
"endedReason": "customer-ended-call"
},
"analysis": {
"summary": "Caller asked about their order …",
"successEvaluated": true,
"structuredData": { "orderId": "A-1187" }
},
"cost": { "stt": 0.0021, "llm": 0.0104, "tts": 0.0090, "total": 0.0215 },
"transcript": [
{ "role": "assistant", "content": "Hi! How can I help?", "startMs": 120, "endMs": 1400 }
]
}
}Verify the signature
If you set a serverUrlSecret, every message carries x-voxa-signature: an HMAC-SHA256 hex digest of the raw request body, keyed by that secret. Compute the same over the exact bytes you received — re-serializing the parsed JSON produces a different digest — and compare before trusting the payload. We encrypt the secret at rest and never return it; reads carry hasServerUrlSecret instead.
import { createHmac } from "crypto";
const expected = createHmac("sha256", serverUrlSecret)
.update(rawRequestBody) // the exact bytes received, not JSON.stringify(parsed)
.digest("hex");
const ok = expected === req.headers["x-voxa-signature"];Delivery
Each attempt times out after 8s and is recorded with the payload we sent and the response we got — visible under Assistant → Server, or via the deliveries endpoint below. Deliveries are kept for 30 days. There are no automatic retries: a non-2xx is logged as a failure, so treat your endpoint as at-most-once and make it fast.
/agents/{id}/server-messages/types agents:readList message types
The catalog of message types this assistant can send.
Path parameters
| id* | uuid | Agent id. |
curl https://api.bolchoai.in/v1/agents/{id}/server-messages/types -H "Authorization: Bearer $BOLCHO_API_KEY"Response
["status-update", "end-of-call-report", "tool-calls"]/agents/{id}/server-messages/deliveries agents:readDelivery log
Recent delivery attempts, with the payload sent and the response received.
Path parameters
| id* | uuid | Agent id. |
Query parameters
| messageType | string | Filter by message type. |
| success | boolean | Filter to successes or failures. |
| limit | number | Page size (1–100, default 20). |
curl https://api.bolchoai.in/v1/agents/$ID/server-messages/deliveries \
-H "Authorization: Bearer $BOLCHO_API_KEY"Response
{ "data": [ { "id": "…", "messageType": "end-of-call-report", "url": "https://…", "success": true, "statusCode": 200, "durationMs": 142, "createdAt": "…" } ], "total": 1, "limit": 20, "offset": 0 }/agents/{id}/server-messages/test agents:writeSend test message
Deliver a signed `ping` to the configured server URL and return the outcome. Ignores serverMessages — you're testing the endpoint, not a subscription.
Path parameters
| id* | uuid | Agent id. |
curl -X POST https://api.bolchoai.in/v1/agents/{id}/server-messages/test -H "Authorization: Bearer $BOLCHO_API_KEY"Response
{ "success": true, "statusCode": 200, "durationMs": 142 }