Receiving webhooks
Get Blueticks events — message delivery, incoming WhatsApp messages, group activity, sessions, campaigns — POSTed to your server in real time.
Webhooks push Blueticks events to your server over HTTPS, in near real time — so you can react to message delivery, incoming WhatsApp messages, group activity, session changes, and campaign progress without polling the API.
This guide assumes you have an API key (Authentication) and an SDK client set up (Quickstart).
1. Register a webhook
Point an HTTPS endpoint at Blueticks and subscribe it to the events you care about (pick any from the catalog below). You can register several endpoints, each with its own event list.
created = bt.webhooks.create(
url="https://api.your-server.com/bt-webhooks",
events=["message.delivered", "message.failed"],
description="prod",
)
print(created.id)const webhook = await bt.webhooks.create({
url: 'https://api.your-server.com/bt-webhooks',
events: ['message.delivered', 'message.failed'],
});$created = $bt->webhooks->create(
url: 'https://api.your-server.com/bt-webhooks',
events: ['message.delivered', 'message.failed'],
);
echo $created->id;created = client.webhooks.create(
url: "https://api.your-server.com/bt-webhooks",
events: ["message.delivered", "message.failed"],
description: "prod",
)
puts created.idcreated, _ := c.Webhooks.Create(context.Background(), blueticks.CreateWebhookParams{
URL: "https://api.your-server.com/bt-webhooks",
Events: []string{"message.delivered", "message.failed"},
Description: "prod",
})
fmt.Println(created.ID)curl -X POST https://api.blueticks.co/v1/webhooks \
-H "Authorization: Bearer BLUETICKS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url":"https://api.your-server.com/bt-webhooks",
"events":["message.delivered","message.failed"]
}'Prefer no code? You can also add and toggle webhooks from the dashboard under Settings → API → Webhooks.
2. What you receive
Each event is a single HTTPS POST. The body is always the same envelope —
only type and data change:
{
"id": "evt_01h7za9c8m...",
"type": "message.delivered",
"created_at": "2026-04-23T16:42:00.000Z",
"data": { /* fields specific to this event type */ }
}with these headers:
Content-Type: application/json
Blueticks-Webhook-Id: 6a380a8258bece30b485036eidis unique per delivery — store it and ignore repeats, since a retry can re-deliver an event your server already handled (see Reliability).Blueticks-Webhook-Idis the id of your webhook that matched — handy when one server backs several endpoints.- Respond
2xxwithin 10 seconds. Anything else (or a timeout) is treated as a failure and retried. Do heavy work after you respond.
3. Events you can subscribe to
You only receive the events you subscribe to. Group them however you like across one or more endpoints.
Message delivery — lifecycle of messages you send:
message.queued · message.sending · message.delivered · message.read · message.failed
Incoming WhatsApp activity:
new_message_received_webhook— someone messaged youreply_to_my_message_webhook— a reply to one of your messagesmessage_edited_webhook·message_deleted_revoked_webhook— a message was edited / deletedmessage_reaction_webhook— an emoji reactionpoll_vote_webhook— a vote on your pollack_changed_webhook— a message's delivered/read status changed
Group & chat activity:
participant_joined_via_link_webhook·participant_added_by_admin_webhook·participant_left_group_webhook·participant_kicked_from_group_webhookgroup_admin_changed_webhook·group_name_changed_webhook·group_description_changed_webhook·group_message_pinned_webhook
Sessions — session.connected · session.disconnected
Campaigns — campaign.started · campaign.paused · campaign.resumed · campaign.completed · campaign.aborted
The Create webhook reference lists the exact accepted enum.
4. Verify requests really came from Blueticks
Blueticks does not sign webhook payloads. To confirm a request is genuinely from us, register a URL containing a secret only you know — a hard-to-guess path segment or query string — and reject any POST that doesn't carry it:
https://api.your-server.com/bt-webhooks?token=ek3f9q2...Always serve the endpoint over HTTPS so that secret stays private in transit.
5. Reliability: retries & auto-disable
- Each delivery attempt must complete within 10 seconds.
- A non-2xx response or a timeout is retried — up to 8 attempts total (the
first delivery plus 7 retries) over roughly 21 hours, with growing backoff
between attempts:
1m → 5m → 15m → 1h → 2h → 6h → 12h. - Because of retries, the same event can arrive more than once — dedupe on
the delivery
id. - After 8 consecutive failures, the endpoint auto-disables. Once your
server is healthy, re-enable it by patching
status: "enabled"(next section).
6. Manage your webhooks
List every endpoint, fetch one by id, change its URL / events / status, or delete it:
curl -X GET 'https://api.blueticks.co/v1/webhooks' \ -H 'Authorization: Bearer BLUETICKS_API_KEY'import blueticksbt = blueticks.Blueticks(api_key="BLUETICKS_API_KEY")result = bt.webhooks.list()import { Blueticks } from 'blueticks';const bt = new Blueticks({ apiKey: 'BLUETICKS_API_KEY' });const result = await bt.webhooks.list();use Blueticks\Blueticks;$bt = new Blueticks(['apiKey' => 'BLUETICKS_API_KEY']);$result = $bt->webhooks->list();require "blueticks"client = Blueticks::Client.new(api_key: "BLUETICKS_API_KEY")result = client.webhooks.list()import ( "context" blueticks "github.com/serenix-com/blueticks-go")client, _ := blueticks.NewClient(blueticks.WithAPIKey("BLUETICKS_API_KEY"))result, _ := client.Webhooks.List(context.Background())curl -X GET 'https://api.blueticks.co/v1/webhooks/string' \ -H 'Authorization: Bearer BLUETICKS_API_KEY'import blueticksbt = blueticks.Blueticks(api_key="BLUETICKS_API_KEY")result = bt.webhooks.get( "id_01H7...",)import { Blueticks } from 'blueticks';const bt = new Blueticks({ apiKey: 'BLUETICKS_API_KEY' });const result = await bt.webhooks.get('id_01H7...');use Blueticks\Blueticks;$bt = new Blueticks(['apiKey' => 'BLUETICKS_API_KEY']);$result = $bt->webhooks->retrieve('id_01H7...');require "blueticks"client = Blueticks::Client.new(api_key: "BLUETICKS_API_KEY")result = client.webhooks.get( "id_01H7...",)import ( "context" blueticks "github.com/serenix-com/blueticks-go")client, _ := blueticks.NewClient(blueticks.WithAPIKey("BLUETICKS_API_KEY"))result, _ := client.Webhooks.Get(context.Background(), "id_01H7...")curl -X PATCH 'https://api.blueticks.co/v1/webhooks/string' \ -H 'Authorization: Bearer BLUETICKS_API_KEY' \ -H 'Content-Type: application/json' \ -d '{ "url": "https://example.com", "events": [ "message.queued" ], "description": "string", "status": "enabled"}'import blueticksbt = blueticks.Blueticks(api_key="BLUETICKS_API_KEY")result = bt.webhooks.update( "id_01H7...", # request body fields…,)import { Blueticks } from 'blueticks';const bt = new Blueticks({ apiKey: 'BLUETICKS_API_KEY' });const result = await bt.webhooks.update('id_01H7...', { /* … */ });use Blueticks\Blueticks;$bt = new Blueticks(['apiKey' => 'BLUETICKS_API_KEY']);$result = $bt->webhooks->update('id_01H7...', /* opts */);require "blueticks"client = Blueticks::Client.new(api_key: "BLUETICKS_API_KEY")result = client.webhooks.update( "id_01H7...", # request body fields…,)import ( "context" blueticks "github.com/serenix-com/blueticks-go")client, _ := blueticks.NewClient(blueticks.WithAPIKey("BLUETICKS_API_KEY"))result, _ := client.Webhooks.Update(context.Background(), "id_01H7...", params){ "url": "https://example.com", "events": [ "message.queued" ], "description": "string", "status": "enabled"}curl -X DELETE 'https://api.blueticks.co/v1/webhooks/string' \ -H 'Authorization: Bearer BLUETICKS_API_KEY'import blueticksbt = blueticks.Blueticks(api_key="BLUETICKS_API_KEY")result = bt.webhooks.delete( "id_01H7...",)import { Blueticks } from 'blueticks';const bt = new Blueticks({ apiKey: 'BLUETICKS_API_KEY' });const result = await bt.webhooks.delete('id_01H7...');use Blueticks\Blueticks;$bt = new Blueticks(['apiKey' => 'BLUETICKS_API_KEY']);$result = $bt->webhooks->delete('id_01H7...');require "blueticks"client = Blueticks::Client.new(api_key: "BLUETICKS_API_KEY")result = client.webhooks.delete( "id_01H7...",)import ( "context" blueticks "github.com/serenix-com/blueticks-go")client, _ := blueticks.NewClient(blueticks.WithAPIKey("BLUETICKS_API_KEY"))result, _ := client.Webhooks.Delete(context.Background(), "id_01H7...")To re-enable an auto-disabled endpoint, PATCH it with status: "enabled" once
your server is healthy again.