Webhooks

Webhook endpoints are how VerifyAI pushes events to you instead of you polling. This page is the REST surface for managing those endpoints — create, list, and delete subscriptions, and choose which events each one receives.

For the receiving side — payload shape, signature verification, retries, and a production handler — see Setting up webhooks.

Authentication

| Header | Required | Value | | ----------- | -------- | ------------------------------------------------------ | | X-API-Key | Yes | A vai_… key with full scope. See Authentication. |

Endpoints are scoped to your customer account — you only ever see and manage your own subscriptions.

The endpoint object

json
{
  "id": "whk_3kf9a2",
  "url": "https://api.yourcompany.com/webhooks/verify-ai",
  "events": ["verification.completed", "verification.reviewed", "inspection.submitted"],
  "status": "active",
  "created_at": "2026-06-01T12:00:00Z"
}

Fields

| Field | Type | Description | | ---------------- | -------- | ------------------------------------------------------------------------------------ | | id | string | Stable endpoint identifier, prefix whk_. Use this to delete. | | url | string | The HTTPS URL we POST deliveries to. Must be HTTPS. | | events | string[] | The event types delivered to this endpoint. See Events. | | status | string | active while delivering. We may set it to disabled after sustained failures. | | created_at | ISO 8601 | When the endpoint was registered. | | signing_secret | string? | The whsec_… HMAC secret. Returned only on create — see below. |

Events

These are the event types you can subscribe an endpoint to. They match the webhook guide exactly.

| Event | Fires when | | ------------------------ | ----------------------------------------------------------------- | | verification.completed | A /v1/verify call finishes processing (compliant or not). | | verification.reviewed | A human review changes a verification's verdict in the dashboard. | | inspection.submitted | A self-inspection session is finalized by the recipient. |

Create an endpoint

text
POST /api/v1/webhooks

Registers an HTTPS URL and the events to deliver there. The response includes the signing secret, returned only this once.

Body parameters

| Parameter | Type | Required | Description | | --------- | -------- | -------- | ------------------------------------------------------------------- | | url | string | Yes | HTTPS URL to receive deliveries. | | events | string[] | Yes | One or more event types from Events. |

curl -X POST https://verify.switchlabs.dev/api/v1/webhooks \
-H "X-API-Key: vai_your_api_key" \
-H "Content-Type: application/json" \
-d '{
  "url": "https://api.yourcompany.com/webhooks/verify-ai",
  "events": ["verification.completed", "verification.reviewed", "inspection.submitted"]
}'
json
{
  "id": "whk_3kf9a2",
  "url": "https://api.yourcompany.com/webhooks/verify-ai",
  "events": ["verification.completed", "verification.reviewed", "inspection.submitted"],
  "signing_secret": "whsec_8mZ4...do_not_log_this",
  "status": "active",
  "created_at": "2026-06-01T12:00:00Z"
}
The signing secret is shown once

signing_secret is returned only on create — we store a hash, so we cannot show it again. Your handler uses it to verify the X-VerifyAI-Signature header on every delivery (HMAC-SHA256 over the raw request body). Copy it into a secret manager immediately. Lost it? Delete the endpoint and create a new one to mint a fresh secret.

List endpoints

text
GET /api/v1/webhooks

Returns every webhook endpoint on your account. The signing_secret is not included — it only appears on the create response.

curl https://verify.switchlabs.dev/api/v1/webhooks \
-H "X-API-Key: vai_your_api_key"
json
{
  "data": [
    {
      "id": "whk_3kf9a2",
      "url": "https://api.yourcompany.com/webhooks/verify-ai",
      "events": ["verification.completed", "verification.reviewed", "inspection.submitted"],
      "status": "active",
      "created_at": "2026-06-01T12:00:00Z"
    }
  ]
}

Delete an endpoint

text
DELETE /api/v1/webhooks/:id

Removes a webhook endpoint by its whk_ id. Deletion is immediate — we stop delivering to that URL right away, and any in-flight retries for it are dropped. To change which events an endpoint receives, delete it and create a new one with the events you want.

curl -X DELETE https://verify.switchlabs.dev/api/v1/webhooks/whk_3kf9a2 \
-H "X-API-Key: vai_your_api_key"
json
{ "id": "whk_3kf9a2", "deleted": true }

Delivery headers

Every delivery we POST to your url carries these headers. Verify the signature over the raw body before parsing — see Setting up webhooks.

| Header | Description | | ---------------------- | --------------------------------------------------------------------- | | X-VerifyAI-Signature | Hex HMAC-SHA256 of the raw request body, keyed by your signing secret. | | X-VerifyAI-Timestamp | UNIX seconds when the delivery was sent. Reject stale timestamps as replays. |

Errors

| Status | Reason | | ------ | ------------------------------------------------------------------- | | 400 | Missing url, a non-HTTPS url, or an empty/unknown events value. | | 401 | Missing or invalid API key. | | 403 | The authenticating key is verify_only and cannot manage webhooks. | | 404 | No webhook endpoint with that id on this account. | | 429 | Rate limit — check the Retry-After header. | | 503 | Authentication service unavailable. Retry. |

What's next

Get in Touch

Questions about pricing, integrations, or custom deployments? We'd love to hear from you.