Webhooks
Endpoints
GET /api/v1/webhooks list
POST /api/v1/webhooks create { url, events[] }
DELETE /api/v1/webhooks/:id delete
POST /api/v1/webhooks/:id/test fire a test eventWebhook fields
typescript
{
user: ObjectId,
team_id: ObjectId | null,
url: string, // your endpoint
events: string[], // subscribed event types
secret: string, // never returned after creation
active: boolean,
failure_count: number,
last_dispatched_at: Date | null,
last_failure_at: Date | null,
}Signing
Every outbound webhook carries a X-Sosyabot-Signature header — the HMAC-SHA256 of the raw body, hex-encoded, signed with the registered secret. Verify on your end:
js
import crypto from "node:crypto";
function verify(req, secret) {
const sig = req.headers["x-sosyabot-signature"];
const expected = crypto.createHmac("sha256", secret).update(req.rawBody).digest("hex");
return crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected));
}Retry
Failed deliveries (non-2xx response, or no response within timeout) increment failure_count. The dispatcher backs off exponentially; persistent failures eventually disable the webhook (active: false).
Common events
post.published, post.failed, account.refresh_failed, billing.invoice.paid, billing.payment_failed, marketplace.order.created, team.invitation.accepted. The exact list is in the source for the dispatcher.