Skip to the page

API reference

Send a test event

Sends an example event of the type you choose to this webhook alone, signed like a real one, and answers once it was tried.

POST/v1/webhooks/{id}/test

Sends an example event of the type you choose to this webhook alone, signed like a real one, and answers once it was tried. Test events never show in the events feed.

Needs a key with the webhooks:manage scope. Keys and scopes

Send an Idempotency-Key so a retry never acts twice. Idempotency

Path parameters

  • idstringrequired

    The webhook’s id.

    Starts with wh_.

Headers

  • Idempotency-Keystring

    Any string of up to 255 characters, new for each request. A retry with the same key gets the first answer back for 24 hours, with Idempotent-Replayed: true.

    Up to 255 characters.

Request body

  • typestring

    Which event to send an example of. Default message.received.

    One of message.queued, message.sent, message.delivered, message.read, message.failed, message.unconfirmed, message.expired, message.canceled, message.received, message.edited, message.unsent, reaction.added, reaction.removed, chat.created, contact.created, contact.stopped, contact.unstopped, sequence.completed, broadcast.completed, automation.matched, device.online, device.offline, device.check_failed.

Example

POST/v1/webhooks/wh_1Hq2LxW9cVbN3mKpRtYs0a/testSend a test event →
curl -X POST "https://usebluebot.com/api/v1/webhooks/wh_1Hq2LxW9cVbN3mKpRtYs0a/test" \
  -H "Authorization: Bearer $BLUEBOT_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 0f6d8c2e-5b1a-4c7e-9d3f-2a8b6e1c4d70" \
  -d '{
    "type": "message.received"
  }'

Response

200: The delivery, after its first try.

  • idstringrequired

    A dlv_ id.

    Starts with dlv_.

  • object"webhook_delivery"required
  • webhook_idstringrequired

    A wh_ id.

    Starts with wh_.

  • event_idstringrequired

    A evt_ id.

    Starts with evt_.

  • event_typestringrequired

    One of message.queued, message.sent, message.delivered, message.read, message.failed, message.unconfirmed, message.expired, message.canceled, message.received, message.edited, message.unsent, reaction.added, reaction.removed, chat.created, contact.created, contact.stopped, contact.unstopped, sequence.completed, broadcast.completed, automation.matched, device.online, device.offline, device.check_failed.

  • testbooleanrequired

    True for an example sent with POST /v1/webhooks/{id}/test.

  • statestringrequired

    pending (trying, or waiting to try again), delivered, gave_up after the last retry, or dropped.

    One of pending, delivered, gave_up, dropped.

  • attemptsintegerrequired
  • last_statusinteger or nullrequired

    The HTTP status of the last try.

  • last_errorstring or nullrequired

    Why the last try failed, when there was no answer.

  • last_duration_msinteger or nullrequired
  • last_response_bodystring or nullrequired

    The first 2 KB of what your endpoint answered on the last try, as text. Null when it answered with no body or not at all.

  • next_attempt_attimestamp or nullrequired

    When it is tried next, while pending.

  • delivered_attimestamp or nullrequired

    When a 2xx answered it.

  • replay_ofstring or nullrequired

    The delivery this one repeats, for a replay.

    Starts with dlv_.

  • created_attimestamprequired

    When it was made.

Response200
{
  "id": "dlv_1Hq2LxW9cVbN3mKpRtYs0a",
  "object": "webhook_delivery",
  "webhook_id": "wh_1Hq2LxW9cVbN3mKpRtYs0a",
  "event_id": "evt_1Hq2LxW9cVbN3mKpRtYs0a",
  "event_type": "message.received",
  "test": true,
  "state": "delivered",
  "attempts": 1,
  "last_status": 200,
  "last_error": null,
  "last_duration_ms": 182,
  "last_response_body": "{\"ok\":true}",
  "next_attempt_at": null,
  "delivered_at": "2026-11-13T19:44:13.000Z",
  "replay_of": null,
  "created_at": "2026-11-13T19:44:12.000Z"
}

Errors

Every refusal has the same envelope and a page of its own. These are the ones this operation can give.

CodeStatusWhat it means
unauthorized401The request carried no key, or a key BlueBot doesn’t know: mistyped, revoked, or a test key sent to the live API.
insufficient_scope403The key doesn’t carry the scope the endpoint needs. Each endpoint’s reference names its scope.
rate_limited429Too many requests. A key may make 120 requests a minute. The RateLimit header says how many are left, and Retry-After how long to wait.
internal500Something went wrong on BlueBot’s side. It was reported. Send the request again; with an Idempotency-Key that is always safe.
invalid_request400Something in the request doesn’t fit: a missing or malformed field, a bad id, or a combination the endpoint refuses. details names each field.
not_found404There is no such thing on this account. Ids are prefixed by kind, so a message id starts with msg_.
idempotency_conflict409The Idempotency-Key was used in the last 24 hours with a different request. A key stands for one request.
conflict409The request doesn’t fit the thing’s current state, or another request with the same Idempotency-Key is still running.

Try it

Call this operation from the page with your own key. The key stays in this tab and is forgotten when you leave.