Webhooks
Tool calls to your server
The request OnCore sends when the assistant invokes one of your tools mid-call.
When you create a tool with a serverUrl, the assistant can invoke it mid-call — and OnCore proxies the invocation to your server. Unlike the lifecycle webhooks, this is a synchronous request/response: the assistant is waiting on the line for your answer, so respond fast.
Request#
OnCore POSTs to the tool's serverUrl:
{
"call_id": "0195f1e2-3333-7000-8000-000000000000",
"arguments": { "firstName": "Alice" },
"metadata": { "language": "en" }
}| Field | Type | Description |
|---|---|---|
call_id | string | The call this invocation belongs to — matches the call_id in the assistant-request and end-of-call report webhooks |
arguments | object | The arguments the model filled in, matching the parameters schema you defined on the tool |
metadata | object | Call context (e.g. the caller's language). Omitted when there is none |
The request carries your client server secret in the x-sadie-core-secret header — verify it exactly as for the other shared-secret webhooks (see the overview):
POST /your-tool-endpoint HTTP/1.1
Content-Type: application/json
x-sadie-core-secret: YOUR_CLIENT_SERVER_SECRETResponse#
Respond synchronously with a 2xx and a JSON body. Your response body is handed back to the assistant as the tool's result, and the model continues the conversation with it.
- For a plain function tool, the shape is yours — return whatever JSON the model should reason over.
- For a dynamic transfer tool, respond with exactly one of the
resolved/ambiguous/not_foundshapes — see the Dynamic transfer guide for the full contract.
app.post("/sadie/tools/find-destination", (req, res) => {
if (req.header("x-sadie-core-secret") !== process.env.SADIE_CLIENT_SERVER_SECRET) {
return res.status(401).end();
}
const { call_id, arguments: args, metadata } = req.body;
// resolve using args, then answer synchronously:
res.json({ status: "resolved", destination: "+15551234567" });
});Failures are spoken, not retried
If your server returns a non-2xx status or is unreachable, the invocation is not retried. The assistant is told the tool call failed and gracefully wraps up with the caller — so treat availability and latency of this endpoint as part of the call experience.