call.answered
POSTed to the number's events_url when the call is answered. Billing for an outbound call starts here.
POSTed to the number's events_url when the call is answered. Billing for an outbound call starts here.
call.answered is sent when the call is answered. Its callSessionState is Answered or Active. When a dial action connects the caller to someone else, a further event arrives with callSessionState: "Bridged".
Outbound calls are billed per second from the moment the other party answers. Ring time is not billed.
Call events are POSTed to the events_url on the number's routing, which you set with PUT /v1/numbers/{id}/routing. They are not workspace webhooks: you cannot subscribe to them with POST /v1/webhooks.
The body is flat JSON.
{
"callSessionState": "Answered",
"direction": "Inbound",
"sessionId": "HD_24d73b4518bc",
"callerNumber": "+254720000000",
"clientDialedNumber": "+254720000001",
"destinationNumber": "+254720000001",
"callStartTime": "2026-06-27+10:00:00",
"isActive": "1"
}| Field | Type | Description |
|---|---|---|
callSessionState | string | Answered or Active for this event; Bridged when a dial action connected. |
direction | string | Inbound or Outbound. |
sessionId | string | The call's id, starting HD_. The same on every event of the call. GET /v1/calls/{id} accepts it. |
callerNumber | string | Who is calling. On an inbound call, the caller's number. |
clientDialedNumber | string | The number that was dialled. On an outbound call, the person you called. |
destinationNumber | string | Your Sautikit number, on inbound and outbound calls. |
callStartTime | string | When the call started. |
isActive | string | "1" while the call is live, "0" once it has ended. |
dialDestinationNumber | string | On Bridged only: the number the dial action connected to. |
Other fields may be present.
events_url one time and is not retried. Respond within 5 seconds; the response body is ignored.X-Sautikit-* headers and no signature. Use an events_url with a path that is hard to guess, and confirm anything that matters with GET /v1/calls/{id}, passing the sessionId.callSessionState says which one it is.import express from "express";
const app = express();
app.use(express.json());
app.post("/sautikit/events", (req, res) => {
res.sendStatus(200); // answer first, then do the work
const event = req.body;
if (["Answered", "Active"].includes(event.callSessionState)) {
console.log(`Call ${event.sessionId} answered`);
// start your own call timer, show the call as live
}
});events_url with PUT /v1/numbers/{id}/routing.GET /v1/calls/{id}.