Skip to main content
Read and manage WhatsApp conversation threads, send messages, and look up senders and templates. Base path https://karibu.briq.tz/v1/whatsapp/*. Every endpoint is workspace-scoped (resolved from your X-API-Key).
Conversations (/conversations/*) read and manage threads. Messages (/messages/*) send and track. Senders (/senders/*) and Templates (/templates/*) are read-only lookups. Sends are async: 202 with { message_id, status: "pending" }, then poll or webhook.
Conversations and Messages use the envelope below. Senders and Templates are older reads that return the data shape directly (no envelope) and a plain 404 { "detail": "..." }.
Try any endpoint live from its page under Karibu WhatsApp in the API reference — add your X-API-Key and send.

Envelope

On failure: success: false, errors: [{ code, message, field }].

Conversations

To read a thread’s messages, filter the messages collection: GET /messages?conversation_id={id}. To find a thread by customer number: GET /conversations?recipient={phone}.

Messages

Each message type has its own send endpoint with a payload scoped to exactly its fields. Open any page and use Try it to send a live request. Send messages Track messages

Senders

Templates

Rules

  • One send endpoint, one send shape. POST /messages, discriminated by type (text / template / media / interactive). Provide exactly one target: to for first contact, or conversation_id to reply (recipient and sender then come from the thread). Sending both, or neither, is 422 VALIDATION_ERROR.
  • Async sends. A send returns 202 { message_id, status: "pending" }. Track via GET /messages/{id} or a webhook.
  • Window. Templates always go and reopen the 24h window; text / media / interactive need an open window or return 422 WINDOW_CLOSED. First contact should be a template.
  • Friendly sender. Filter conversations or pick a send sender with sender: its WhatsApp number, its phone_number_id, or its sender id (UUID). The UUID-only sender_id still works but is deprecated. Conversations and sends echo sender (the phone_number_id) back.
  • Internal ids everywhere. Endpoints take your internal message_id / conversation_id (not provider wamids). The read receipt resolves the provider id for you.
  • Phone format: E.164 digits, optional leading + (e.g. 255712000000). The send to and the ?recipient= filter are validated/normalised the same way.
  • window ({open, expires_at}) reflects the 24-hour service window.
  • Mark-read on a conversation clears inbox unread state; /messages/{id}/read is the WhatsApp read receipt.
  • Delete is soft and one-way; the thread leaves all lists.

Errors

This API never returns a 5xx. Every failure mode is a stable 4xx code above, so your integration can branch on errors[0].code without special-casing server faults. Transient provider problems surface as 422 PROVIDER_UNAVAILABLE (retry), and when a record was created the response still carries a pollable data.message_id. Walkthroughs with examples: conversations guide · messages guide · senders and templates guide.

Webhook events

Sends are async, so delivery status arrives by webhook (poll GET /messages/{id} as the pull alternative). Register a whatsapp webhook for your developer app (see Karibu Webhooks); Briq POSTs each event to it. Every callback is an HTTP POST with this envelope:
  • data.message_id matches the message_id from your send response and GET /messages/{id} — use it to correlate.
  • whatsapp.failed adds data.error_code and data.error_message.
  • whatsapp.received carries from, message_type, content, and profile_name instead of recipient.
  • Status events for messages you sent via the API are routed to your webhook automatically (correlated by your API key); inbound events are routed by workspace.
Events are at-least-once — the same event_id may arrive more than once. Deduplicate on event_id (or event + data.message_id).

Verifying the signature

When your webhook has a signing secret, each request carries X-Briq-Signature plus X-Briq-Service-Type and X-Briq-App-ID. The signature is the HMAC-SHA256 hex digest of the JSON body re-serialized with sorted keys, keyed by your secret:
Sign over json.dumps(payload, sort_keys=True), not the raw bytes — key order is normalized before signing. Reveal or rotate the secret from Karibu Webhooks.