Skip to main content
WEBHOOK

Authorizations

Authorization
string
header
required

Your workspace API key, sent as Authorization: Bearer blu_.... Workspace admins can find it in the Blujay app under API.

An API key has full access to your workspace and works on every endpoint. There is no test mode: every key sends real messages and changes real data, so keep it secret and use it only from your server.

Each API key can make 600 read requests and 120 write requests per minute, plus 60 attachment requests per minute. Over a limit you get 429 RATE_LIMIT_EXCEEDED with Retry-After.

Headers

webhook-id
string
required

The event's unique ID (evt_...), the same as event_id in the body.

webhook-timestamp
string
required

When this delivery was signed, in Unix seconds.

webhook-signature
string
required

v1, followed by the base64 HMAC-SHA256 of {webhook-id}.{webhook-timestamp}.{body}, signed with your base64-decoded whsec_ secret.

Body

application/json
api_version
any
required
webhook_version
enum<string>
required

The payload version for a subscription's events.

  • 2026-08-20 reports the service you asked for as requested_service and the service actually used as service.
  • 2026-09-02 adds message parts.
  • 2026-10-03 adds iMessage group typing with a participants snapshot, and reply_to on message events.

Earlier versions keep their original payload shapes and never receive group typing. Each event uses the subscription's version at the time the event was created, so changing the version affects only later events.

Available options:
2026-06-14,
2026-08-01,
2026-08-20,
2026-09-02,
2026-10-03
event_type
enum<string>
required

Every event type that can appear on a subscription or in a webhook. Some types are recognized only so older subscriptions keep working and may never be sent. You can add only the types in WebhookSubscribableEventType.

Available options:
message.accepted,
message.sent,
message.delivered,
message.read,
message.failed,
message.received,
reaction.added,
reaction.removed,
participant.added,
participant.removed,
chat.group_name_updated,
phone_number.status_updated,
contact.tag_added,
contact.assigned,
chat.typing_indicator.started,
chat.typing_indicator.stopped,
message.edited,
message.unsent
event_id
string
required
Pattern: ^evt_[A-Za-z0-9_-]+$
Example:

"evt_abc123"

created_at
string<date-time>
required
Example:

"2026-10-14T17:01:00.000Z"

trace_id
string
required
Pattern: ^trc_[A-Za-z0-9_-]+$
Example:

"trc_8f2a1c0e4b7d"

workspace_id
string
required
Pattern: ^workspace_[A-Za-z0-9_-]+$
Example:

"workspace_abc123"

subscription_id
string
required
Pattern: ^whsub_[A-Za-z0-9_-]+$
Example:

"whsub_abc123"

data
object
required

The event's details. The shape depends on event_type and the subscription's payload version.

  • Message events on version 2026-09-02 and later include parts. A media part gives the attachment_id, file details and a download_url.
  • Group message.received events include sender on every version.
  • Version 2026-10-03 adds reply_to to every message event (the same object as in message reads, or null). Earlier versions never include it.
  • message.failed events may include a failure_code you can act on. On version 2026-08-01 and later they also include failure with a code and a readable reason. failure.code is one of network_rejected (the messaging network rejected the message), service_mismatch, sender_unavailable, sender_retired, recipient_unavailable, reply_requires_imessage, dispatch_unavailable, unsupported_content (content the selected service can't send, such as a file type or size it doesn't carry) or delivery_failed.

Response

200

Return any 2xx status to acknowledge the event.