Webhooks (dev)
For end-user webhook setup, see Webhooks (user).
Register via GraphQL
mutation {
createWebhook(input: {
name: "my-system"
url: "https://my-system.example.com/vibe-webhook"
events: ["session.started", "session.terminated", "agent.disconnected"]
secret: "..."
retryPolicy: {maxAttempts: 6, backoff: "exponential"}
agentIds: [] # empty = all agents in workspace
}) { id signingKey }
}
Delivery contract
| Property | Value |
|---|---|
| Method | POST |
| Content-Type | application/json |
X-Vibecontrols-Delivery-Id | UUID per delivery attempt (stable across retries) |
X-Vibecontrols-Signature | t=<unix-ts>, v1=<hex-hmac-sha256> |
| Retries | Per webhook's retryPolicy |
| Tracking | Webhook.deliveryCount + failureCount + lastDelivery + lastError |
Verify signature
import {createHmac} from "crypto";
function verify(rawBody: string, sigHeader: string, secret: string): boolean {
const parts = Object.fromEntries(sigHeader.split(",").map(p => p.trim().split("=")));
const expected = createHmac("sha256", secret).update(`${parts.t}.${rawBody}`).digest("hex");
return expected === parts.v1;
}
Idempotency
Use X-Vibecontrols-Delivery-Id — store seen IDs and skip duplicates. Retries reuse the same ID.
Event payload shape
Each event has a stable JSON shape. The full payload schema for each event is documented under the GraphQL WebhookEventType enum in the live schema.