threshold1

Webhooks

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.

Register

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.

List

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

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.

What's next

  • Error Reference — the general error-code taxonomy shared across this API.