Skip to main content
A complete reference for the Webhook Management API. These endpoints let you register a callback URL for a developer app, reveal its signing secret, send test events, and inspect, audit, and retry every delivery attempt.
  • API surface: https://karibu.briq.tz/v1/webhooks/*
  • Audience: backend engineers wiring Briq delivery events into their product.
  • Version: v1
The /v1/webhooks/* routes are shared across all channels. The same routes serve sms, voice, otp, whatsapp, and email - you pick the channel with the service_type field when you create a webhook. For the WhatsApp event payloads delivered to these webhooks, see the Karibu WhatsApp API reference.

1. Overview

A webhook is a callback URL Briq POSTs event payloads to when something happens to a message you sent. To receive events you:
  1. Create a webhook for one of your developer apps, choosing a service_type (e.g. whatsapp).
  2. Fetch the signing secret and store it, so you can verify the X-Briq-Signature header on incoming deliveries.
  3. Return 2xx quickly from your endpoint. Non-2xx responses, timeouts, and connection errors are treated as failures and retried.
Each emitted event is persisted as a delivery row and attempted by Briq’s delivery engine. You can list deliveries, view a single delivery’s full payload, see aggregate stats, and manually retry failed deliveries.
One webhook per app per service_type. Each developer app may have only one webhook for a given channel. Creating a second whatsapp webhook for the same app returns 400. Delete the existing one first to free the slot.

2. Authentication & host

Base URL

https://karibu.briq.tz

Required headers

HeaderRequiredNotes
X-API-KeyyesYour developer API key. Must be active and not expired. Missing/invalid -> 401.
HostyesMust be karibu.briq.tz. Other hosts are rejected with 403 outside development/sandbox environments.
Content-Typeyes (POST/PATCH)application/json
All webhooks you create, read, or manage are scoped to your developer apps (resolved from the API key). A webhook owned by another user is invisible to you - reads return 404.

Response shape

These endpoints return bare resource objects (no success/data/errors envelope). Errors use the raw framework shape:
{ "detail": "Webhook not found" }
Treat any non-2xx status as a failure and read detail for the reason.

3. Endpoint reference

3.1 POST /v1/webhooks/ - Create a webhook

Registers a callback URL for a developer app. The authenticated user must own the app referenced by app_id. A signing secret is generated automatically at creation; retrieve it separately via the secret endpoint. Body:
FieldTypeRequiredDescription
app_idUUIDyesID of the developer app that will receive events. Must be an app you own.
service_typestringyesChannel. One of sms, voice, otp, whatsapp, email (regex ^(sms|voice|otp|whatsapp|email)$).
urlstring (HTTPS URL)yesPublic HTTPS URL we POST event payloads to. Must be reachable and return 2xx on success.
Success - 201 Created:
{
  "webhook_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "app_id": "550e8400-e29b-41d4-a716-446655440000",
  "service_type": "whatsapp",
  "url": "https://api.yourdomain.com/briq/webhooks/whatsapp",
  "secret_token": "***",
  "created_at": "2026-03-15T12:00:00.000000",
  "updated_at": "2026-03-15T12:00:00.000000"
}
The returned secret_token is always masked as ***. Fetch the real value with the secret endpoint.
HTTPCause
400App not found, not owned by you, or a webhook for this app + service_type already exists.
422Invalid body (bad service_type, non-HTTPS/malformed url, non-UUID app_id).
curl -X POST "https://karibu.briq.tz/v1/webhooks/" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "app_id": "550e8400-e29b-41d4-a716-446655440000",
    "service_type": "whatsapp",
    "url": "https://api.yourdomain.com/briq/webhooks/whatsapp"
  }'

3.2 GET /v1/webhooks/all - List all webhooks for the user

Returns every webhook belonging to the authenticated user, across all developer apps and channels. Returns an empty array [] if you have none (not an error). Success - 200 OK: an array of webhook objects (same shape as the create response).
curl "https://karibu.briq.tz/v1/webhooks/all" \
  -H "X-API-Key: YOUR_API_KEY"

3.3 GET /v1/webhooks/app/{app_id} - List webhooks for an app

Lists the webhooks registered for a single developer app you own. If the app is not yours or has no webhooks, an empty array [] is returned. Path parameter: app_id (string, required).
curl "https://karibu.briq.tz/v1/webhooks/app/550e8400-e29b-41d4-a716-446655440000" \
  -H "X-API-Key: YOUR_API_KEY"

3.4 GET /v1/webhooks/{webhook_id} - Get a webhook

Fetches a single webhook by ID. Must belong to one of your apps, otherwise 404. Path parameter: webhook_id (string, required). Success - 200 OK: a single webhook object.
HTTPCause
404Webhook not found or not owned by one of your apps ({"detail": "Webhook not found"}).
curl "https://karibu.briq.tz/v1/webhooks/a1b2c3d4-e5f6-7890-abcd-ef1234567890" \
  -H "X-API-Key: YOUR_API_KEY"

3.5 PATCH /v1/webhooks/{webhook_id} - Update a webhook

Updates a webhook’s url and/or service_type. Both fields are optional; send only what you want to change. Body:
FieldTypeRequiredDescription
service_typestringnoNew channel (same enum as create).
urlstring (HTTPS URL)noNew public HTTPS callback URL.
The signing secret is fixed at creation and is not affected by an update. Existing receivers keep verifying X-Briq-Signature with the same secret.
HTTPCause
404Webhook not found, not owned by one of your apps, or the update failed.
422Invalid body (bad service_type or malformed/non-HTTPS url).
curl -X PATCH "https://karibu.briq.tz/v1/webhooks/a1b2c3d4-e5f6-7890-abcd-ef1234567890" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "url": "https://api.yourdomain.com/briq/webhooks/whatsapp-v2" }'

3.6 DELETE /v1/webhooks/{webhook_id} - Delete a webhook

Permanently removes a webhook. After deletion, Briq stops sending events to its URL, and the per-service_type uniqueness slot is freed (you can create a new one for the same app + channel). Success - 204 No Content (no body).
HTTPCause
404Webhook not found or not owned by one of your apps.
curl -X DELETE "https://karibu.briq.tz/v1/webhooks/a1b2c3d4-e5f6-7890-abcd-ef1234567890" \
  -H "X-API-Key: YOUR_API_KEY"

3.7 GET /v1/webhooks/{webhook_id}/secret - Reveal signing secret

Returns the webhook’s signing secret in plaintext. Use it to verify the X-Briq-Signature header (HMAC-SHA256 of the raw request body) on incoming deliveries. Success - 200 OK:
{ "secret_token": "whsec_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" }
HTTPCause
404Webhook not found / not owned ({"detail": "Webhook not found"}) or webhook has no secret set ({"detail": "Webhook has no secret"}).
Treat the secret as a credential. Store it in a secret manager or environment variable; never expose it client-side. The full HMAC verification procedure (header format, raw-body handling, sample code) is documented in the WhatsApp reference -> Verifying the signature.
curl "https://karibu.briq.tz/v1/webhooks/a1b2c3d4-e5f6-7890-abcd-ef1234567890/secret" \
  -H "X-API-Key: YOUR_API_KEY"

3.8 POST /v1/webhooks/{webhook_id}/test - Send a test event

Enqueues a synthetic test delivery so you can confirm your endpoint is reachable and your signature verification works. Returns an event_id you can use to find the delivery. Success - 202 Accepted:
{
  "event_id": "test_9f8e7d6c5b4a3210",
  "message": "Test event enqueued. Poll GET /{webhook_id}/deliveries to check status."
}
Synthetic sms.sent payload quirk. The test endpoint currently emits a synthetic sms.sent event regardless of the webhook’s service_type. For a whatsapp webhook this still verifies connectivity and signature verification, but the body is not a faithful WhatsApp event payload. A native whatsapp.* test event is upcoming.
curl -X POST "https://karibu.briq.tz/v1/webhooks/a1b2c3d4-e5f6-7890-abcd-ef1234567890/test" \
  -H "X-API-Key: YOUR_API_KEY"

3.9 GET /v1/webhooks/{webhook_id}/deliveries - List delivery attempts

Returns a paginated, filterable list of delivery attempts for a webhook so you can audit what was sent, the HTTP status received, and any errors. Query parameters:
FieldTypeRequiredDescription
statusstringnopending, delivered, failed, or exhausted.
event_namestringnoFilter by event name (e.g. briq.message.delivered).
from_created_atdatetime (ISO 8601)noCreated on or after this timestamp.
to_created_atdatetime (ISO 8601)noCreated on or before this timestamp.
message_idstringnoFilter by message ID.
limitintnoPage size, 1-100. Default 50.
offsetintnoItems to skip, >= 0. Default 0.
Success - 200 OK:
{
  "items": [
    {
      "id": "d1e2f3a4-b5c6-7890-abcd-ef0123456789",
      "event_id": "evt_0a1b2c3d4e5f",
      "webhook_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "app_id": "550e8400-e29b-41d4-a716-446655440000",
      "service_type": "whatsapp",
      "event_name": "briq.message.delivered",
      "status": "failed",
      "attempt_count": 3,
      "max_attempts": 5,
      "last_status_code": 500,
      "last_error": "Internal Server Error",
      "next_attempt_at": "2026-03-15T12:10:00.000000",
      "created_at": "2026-03-15T12:00:00.000000",
      "updated_at": "2026-03-15T12:05:00.000000"
    }
  ],
  "total": 1,
  "limit": 20,
  "offset": 0
}
Delivery summary fields
FieldTypeDescription
idstringUnique delivery id. Use it with the get-one-delivery endpoint.
event_idstringEvent id from the envelope (idempotency).
webhook_idstringTarget webhook config id.
app_idstring | nullDeveloper app id.
service_typestringChannel: sms, email, voice, otp, whatsapp.
event_namestringEvent name.
statusstringpending | delivered | failed | exhausted.
attempt_countintNumber of delivery attempts made.
max_attemptsintMaximum attempts configured.
last_status_codeint | nullHTTP status from the last attempt.
last_errorstring | nullLast error message if failed.
next_attempt_atdatetime | nullWhen the next attempt is due.
created_at / updated_atdatetimeTimestamps.
List items omit the url and payload fields. Use get-one-delivery for the full payload snapshot.
curl "https://karibu.briq.tz/v1/webhooks/a1b2c3d4-e5f6-7890-abcd-ef1234567890/deliveries?status=failed&limit=20" \
  -H "X-API-Key: YOUR_API_KEY"

3.10 GET /v1/webhooks/{webhook_id}/stats - Delivery stats

Returns aggregated delivery outcome counts over a time window, broken down by status and event name. Useful for monitoring health and spotting failure spikes. Query parameter: since (datetime, ISO 8601, optional). Defaults to 7 days ago. Success - 200 OK:
{
  "webhook_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "since": "2026-03-01T00:00:00.000000",
  "total": 124,
  "by_status": { "delivered": 118, "failed": 4, "exhausted": 1, "pending": 1 },
  "by_event": { "briq.message.delivered": 100, "briq.message.failed": 24 }
}
curl "https://karibu.briq.tz/v1/webhooks/a1b2c3d4-e5f6-7890-abcd-ef1234567890/stats?since=2026-03-01T00:00:00Z" \
  -H "X-API-Key: YOUR_API_KEY"

3.11 GET /v1/webhooks/deliveries/{delivery_id} - Get one delivery

Returns the full detail for a single delivery, including the target url and the payload snapshot of the JSON body that was sent (or is queued to send). Path parameter: delivery_id (string, required) - the id from a delivery list item. Success - 200 OK: every delivery-summary field plus:
FieldTypeDescription
urlstringCallback URL this delivery targets.
payloadobject | nullSnapshot of the JSON body sent or to be sent.
HTTPCause
404Delivery not found or not owned by one of your apps.
curl "https://karibu.briq.tz/v1/webhooks/deliveries/d1e2f3a4-b5c6-7890-abcd-ef0123456789" \
  -H "X-API-Key: YOUR_API_KEY"

3.12 POST /v1/webhooks/deliveries/{delivery_id}/retry - Retry a delivery

Schedules a previously failed delivery for another attempt. Only deliveries with status failed or exhausted can be retried. Success - 200 OK: the updated delivery detail (typically status: "pending" with next_attempt_at set).
HTTPCause
404Delivery not found or not owned by one of your apps.
422Delivery is not in a retryable state (status is not failed or exhausted).
Retry requeues the same delivery row - it does not create a duplicate. The same id is updated and re-attempted.
curl -X POST "https://karibu.briq.tz/v1/webhooks/deliveries/d1e2f3a4-b5c6-7890-abcd-ef0123456789/retry" \
  -H "X-API-Key: YOUR_API_KEY"

4. What your endpoint must return

Your HTTP responseBriq behavior
Any 2xxTreated as success; Briq stops retrying this attempt.
Non-2xx, timeout, or connection failureTreated as failure; retried with backoff up to max_attempts.
The response body is not interpreted for success - 204 No Content or 200 OK with an empty body is sufficient. Respond quickly (acknowledge, then process asynchronously) so your endpoint isn’t marked as failing under load.
  • Karibu WhatsApp API - WhatsApp send/read endpoints and the whatsapp.sent/delivered/read/failed event payloads delivered to these webhooks.
  • Webhooks (subscriber guide) - what your HTTPS endpoint receives, signature verification, idempotency, and retry behavior.
  • Developer Apps - API keys and app configuration.