Three endpoints, all API-key authenticated. Live-verified end to end, including a real delivery landing at a real external URL with a real signature.
POST /api/v1/webhooks
Authorization: Bearer th_test_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Content-Type: application/json
{ "url": "https://your-server.com/webhooks/threshold1" }
Real response, captured live:
{
"success": true,
"webhook": {
"id": "e6cda304-3b26-48bb-842c-067fedf94be3",
"url": "https://your-server.com/webhooks/threshold1",
"secret": "dd4315be2f13cb394c80e75cada0cce9454d2cc661f47b98accb480f617c7f7a"
}
}
secret signs every delivery this webhook receives (X-Threshold1-Signature, hex HMAC-SHA256 of the raw payload) — save it, it isn't shown again.
Real delivery, confirmed live end to end: registered a real webhook, triggered a real user registration on the same project, and the real payload arrived at a real external endpoint:
{ "id": "b4ea106f-...", "type": "user.registered", "created_at": "2026-08-25T17:25:52...", "data": { "email": "user@example.com", "user_id": "36dda2c7-..." } }
with a real X-Threshold1-Signature header present and verifiable against the registration's own secret.
GET /api/v1/webhooks
Authorization: Bearer th_test_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Real response:
{
"success": true,
"webhooks": [
{ "id": "e6cda304-...", "project_id": "0f5b1681-...", "url": "https://...", "secret": "...", "created_at": "2026-08-25T18:14:01...", "event_types": null }
]
}
event_types: null means the webhook receives every event type. Pass eventTypes as an array at registration time to subscribe to specific ones only.
DELETE /api/v1/webhooks/:id
Authorization: Bearer th_test_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Real response: { "success": true }. A non-existent ID returns a real captured error:
{ "success": false, "error": "Webhook not found" }
404
A real, current limitation worth knowing before you rely on this: deleting a webhook that already has delivery history attached to it fails — confirmed live, not assumed. The real response is an unhandled 500 with a raw database error, not a clean error code:
{ "success": false, "error": "Failed to delete webhook: update or delete on table \"webhooks\" violates foreign key constraint \"webhook_deliveries_webhook_id_fkey\" on table \"webhook_deliveries\"" }
This is a separate, newly-found issue from the projectId/companyId bug these three endpoints previously had — that one is fixed as of this same docs batch (registration and listing now correctly scope to your project; earlier, every real registration attempt failed outright). This delete-with-history limitation is not yet fixed — if you need to remove a webhook that's actually received deliveries, this endpoint won't currently do it cleanly.