SYS: OPERATIONALUPTIME: 99.8%

GUIDES

Webhooks

Webhooks let your application receive real-time notifications when events occur in your agent infrastructure. Use them for monitoring, analytics, and event-driven workflows.

Setting Up a Webhook Endpoint

First, create an HTTP endpoint that can receive POST requests:

Express endpoint
import express from "express"; import crypto from "crypto"; const app = express(); app.use(express.raw({ type: "application/json" })); const WEBHOOK_SECRET = process.env.YA_WEBHOOK_SECRET!; app.post("/webhooks/ya-events", (req, res) => { // 1. Verify signature const signature = req.headers["x-ya-webhook-signature"] as string; const timestamp = req.headers["x-ya-webhook-timestamp"] as string; const body = req.body.toString(); const expected = crypto .createHmac("sha256", WEBHOOK_SECRET) .update(`${timestamp}.${body}`) .digest("hex"); if (!crypto.timingSafeEqual( Buffer.from(signature.replace("sha256=", "")), Buffer.from(expected) )) { return res.status(401).json({ error: "Invalid signature" }); } // 2. Process the event const event = JSON.parse(body); switch (event.type) { case "execution.completed": console.log("Execution completed:", event.data.executionId); break; case "execution.failed": console.error("Execution failed:", event.data.error); break; case "tool.error": console.error("Tool error:", event.data.toolName, event.data.error); break; } // 3. Respond with 200 to acknowledge receipt res.status(200).json({ received: true }); }); app.listen(3000);

Register the Webhook

Register via SDK
const webhook = await client.webhooks.create({ url: "https://api.example.com/webhooks/ya-events", events: [ "execution.completed", "execution.failed", "tool.error", ], agentId: "agt_abc123", // optional: filter by agent }); // Save the secret for signature verification console.log("Webhook secret:", webhook.secret); // Store this securely (env variable)

Event Payload Examples

execution.completed
{ "id": "evt_abc123", "type": "execution.completed", "data": { "executionId": "exec_def456", "agentId": "agt_ghi789", "conversationId": "conv_jkl012", "status": "completed", "output": "I've processed your return request...", "toolCalls": [ { "name": "initiate_return", "duration": 234 } ], "usage": { "totalTokens": 231 }, "timing": { "totalMs": 1234 } }, "createdAt": "2026-03-15T10:30:00Z" }
execution.failed
{ "id": "evt_def456", "type": "execution.failed", "data": { "executionId": "exec_ghi789", "agentId": "agt_jkl012", "error": { "type": "upstream_error", "code": "model_unavailable", "message": "The model is temporarily unavailable" } }, "createdAt": "2026-03-15T10:30:00Z" }
tool.error
{ "id": "evt_ghi789", "type": "tool.error", "data": { "executionId": "exec_jkl012", "agentId": "agt_mno345", "toolName": "lookup_order", "error": { "code": "TIMEOUT", "message": "Tool handler did not respond within 10000ms" } }, "createdAt": "2026-03-15T10:30:00Z" }

Monitoring Dashboard

Use webhooks to build a monitoring pipeline:

Monitoring pipeline
// Send metrics to your analytics platform app.post("/webhooks/ya-events", (req, res) => { const event = JSON.parse(req.body.toString()); if (event.type === "execution.completed") { // Track in your analytics analytics.track("agent_execution", { agentId: event.data.agentId, duration: event.data.timing.totalMs, tokens: event.data.usage.totalTokens, toolCalls: event.data.toolCalls.length, }); } if (event.type === "execution.failed") { // Alert on failures alerting.send({ channel: "#agent-alerts", message: `Agent ${event.data.agentId} failed: ${event.data.error.message}`, severity: "high", }); } res.status(200).json({ received: true }); });

Note

Always respond to webhook deliveries within 5 seconds with a 2xx status code. If your processing takes longer, acknowledge receipt immediately and process asynchronously.

Testing Webhooks Locally

Use a tunnel service during development to receive webhooks on localhost:

Local testing
# Using ngrok ngrok http 3000 # Register the ngrok URL as your webhook await client.webhooks.create({ url: "https://abc123.ngrok.io/webhooks/ya-events", events: ["execution.completed"], });