Skip to main content
POST
Create a partner webhook subscription

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.

Reseller partner keys. A partner key acts for one of the partner's customers when the request names it in the Blujay-Workspace header (the customer's workspace_ ID). Without the header it reaches only /v1/partner/* and /v1/me. Each customer gets the limits above for each partner key, and all of a partner's requests together get ten times those limits; a 429 says which in error.details[0].scope (partner_customer or partner). A messaging key can read anything for a customer and change chats, messages, contacts, attachments and vCards; everything else needs an admin key (403 PARTNER_ROLE_FORBIDDEN). Paused or closing customers can be read but not changed (409 CUSTOMER_PAUSED or CUSTOMER_CLOSING). Any other workspace ID in the header returns 404 NOT_FOUND; using the header with any other credential returns 400 WORKSPACE_HEADER_NOT_ALLOWED.

Body

application/json
url
string<uri>
required

Your HTTPS endpoint, up to 2,048 characters. It must resolve to a public address.

Maximum string length: 2048
Example:

"https://example.com/webhooks/blujay"

event_types
enum<string>[]
required

The events to send (1–100). Customer events go to this subscription; every other type is sent for every customer.

Required array length: 1 - 100 elements

Any event a workspace subscription can take, plus the customer events.

Available options:
message.accepted,
message.sent,
message.delivered,
message.read,
message.failed,
message.received,
reaction.added,
reaction.removed,
phone_number.status_updated,
contact.tag_added,
contact.assigned,
chat.typing_indicator.started,
chat.typing_indicator.stopped,
participant.added,
participant.removed,
chat.group_name_updated,
message.edited,
message.unsent,
call.ended,
call.recording_ready,
phone_number.assigned,
phone_number.released
webhook_version
enum<string>
default:2026-10-30

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, reply_to on message events, voice memos as audio parts (2026-09-02 reports them as media parts), and saved on the contact in contact.tag_added and contact.assigned.
  • 2026-10-30 reports contacts' emoji reactions as reaction.added / reaction.removed with type custom and emoji, and stickers with type sticker and sticker. Earlier versions receive them as message.received, as before.

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,
2026-10-30
status
enum<string>
default:active
Available options:
active,
disabled

Response

The new subscription, including its signing_secret.

Wraps every successful response. The result is in data.

status
enum<string>
required
Available options:
success
trace_id
string
required
Pattern: ^trc_[A-Za-z0-9_-]+$
Example:

"trc_8f2a1c0e4b7d"

timestamp
string<date-time>
required
Example:

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

data
object
required

One endpoint that receives every customer's events. Each event's workspace_id names the customer.

client_request_id
string

Your X-Request-ID header value, echoed back when you send one. Not included on the send responses (POST /v1/chats and POST /v1/chats/{chat_id}/messages); keep your own mapping from your request ID to the returned message ID there.