Tutorials
Give an assistant a tool
Let an assistant look up real data mid-conversation by pointing it at an endpoint you control.
A tool turns an assistant from something that talks into something that knows. In this tutorial you will stand up an order-status endpoint, register it as a tool, attach it to an assistant, and watch it get called during a live conversation.
You will need: the webhook receiver from the previous tutorial running behind a tunnel, and your API key.
Write the endpoint#
A tool endpoint is an ordinary HTTP handler. Keep it fast — this runs inside a live conversation while the caller waits.
const ORDERS = {
"1001": { status: "shipped", carrier: "DHL", eta: "Thursday" },
"1002": { status: "processing", carrier: null, eta: "next week" },
};
app.post("/tools/order-status", express.json(), (req, res) => {
if (req.header("x-sadie-core-secret") !== process.env.ONCORE_CLIENT_SERVER_SECRET) {
return res.status(401).end();
}
const { orderNumber } = req.body ?? {};
const order = ORDERS[String(orderNumber ?? "").trim()];
// Answer even when you cannot answer — a clear "not found" is far better
// for the assistant than an error it has to improvise around.
if (!order) {
return res.json({ found: false, message: `No order ${orderNumber}.` });
}
res.json({ found: true, ...order });
});Register it as a tool#
The description is the most important field in this request. It is what the model reads when deciding whether to call your tool, so write it for a reader who knows nothing about your system.
curl -X POST https://core-api.heysadie.ai/tools \
-H "Authorization: ApiKey YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "order_status",
"description": "Look up the delivery status of a customer order by its order number. Use this whenever a caller asks where their order is, when it will arrive, or whether it has shipped.",
"url": "https://YOUR-TUNNEL.ngrok.app/tools/order-status"
}'Vague descriptions are why tools do not fire
"Gets order data" will be selected unreliably. Name the user's intent — when a caller asks where their order is — and the model has something to match against.
TODO — verify
The exact request body for POST /tools, including how parameters are declared, is documented in the Tools API reference. Confirm the field names there against the live spec before copying this into production.
Attach it to an assistant#
A tool defined in your tenant is not yet available to any assistant. Add its id to toolIds:
curl -X PATCH https://core-api.heysadie.ai/assistants/ASSISTANT_ID \
-H "Authorization: ApiKey YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "toolIds": ["TOOL_ID_FROM_STEP_2"] }'toolIds replaces the whole list rather than appending, so include every tool the assistant should keep.
Tell the assistant it can help#
The model uses the tool when the conversation calls for it, but a nudge in the prompt makes it far more reliable:
curl -X PATCH https://core-api.heysadie.ai/assistants/ASSISTANT_ID \
-H "Authorization: ApiKey YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"developerPrompt": "You help customers with their orders. When someone asks about an order, ask for the order number and look it up before answering. Never guess a delivery date."
}'Call it#
Ring the assistant and ask where order 1001 is. You should see the request hit your terminal, and hear the assistant answer with the real carrier and ETA.
If nothing fires, work through the tool checklist in Calls and assistant behavior.
:::
Making it production-worthy#
Respond fast. The caller is waiting in silence. Aim well under a second; return partial data rather than stalling.
Never fail silently. A 500 leaves the assistant with nothing to say. Return a structured "not found" instead — the model handles that gracefully.
Verify every request. Your tool endpoint is a public URL. Check x-sadie-core-secret on every call, exactly as you do for webhooks.
Return only what is needed. Everything you return enters the conversation context. Send the three fields the caller asked about, not your whole order record.
Next#
- Tools — the full tool model, including dynamic transfer.
- Tool calls to your server — the exact request shape OnCore sends.
- Tools API — endpoint reference.