Skip to main content
GET
/
v1
/
messages
/
bulk
/
{broadcastId}
Status of a previously scheduled bulk broadcast
curl --request GET \
  --url https://api.keebai.com/v1/messages/bulk/{broadcastId} \
  --header 'Authorization: Bearer <token>'
{
  "broadcast_id": "<string>",
  "status": "<string>",
  "total_recipients": 123,
  "sent": 123,
  "failed": 123,
  "pending": 123,
  "started_at": "<string>",
  "completed_at": "<string>"
}
Returns the status of a broadcast created by POST /v1/messages/bulk or by any single send (/v1/messages/template, /v1/messages/text), which internally also creates a broadcast.

Endpoint

GET https://api.keebai.com/v1/messages/bulk/:broadcastId

Required scope

messages:bulk

Headers

HeaderRequiredValue
AuthorizationYesBearer kbai_pk_<token>

Path params

ParamTypeDescription
broadcastIdstringObjectId of the broadcast returned when the send was created.

Example request

curl https://api.keebai.com/v1/messages/bulk/65f4b5c6d7e8f9a0b1c2d3e4 \
  -H "Authorization: Bearer kbai_pk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

Response

200 OK

{
  "broadcast_id": "65f4b5c6d7e8f9a0b1c2d3e4",
  "status": "IN_PROGRESS",
  "total_recipients": 1500,
  "sent": 980,
  "failed": 12,
  "pending": 508,
  "started_at": "2026-04-25T13:45:02.123Z",
  "completed_at": null
}
FieldTypeDescription
broadcast_idstringSame id you requested.
statusstringPENDING, IN_PROGRESS, COMPLETED, FAILED, CANCELLED.
total_recipientsnumberTotal recipients at broadcast creation.
sentnumberMessages Meta confirmed as sent.
failednumberMessages that failed (rejected by Meta or dispatch error).
pendingnumberMessages still in queue.
started_atstring | nullISO 8601 timestamp when processing started. null if not started yet.
completed_atstring | nullISO 8601 timestamp when processing finished. null if still in progress.

400 Bad Request

broadcastId is not a valid ObjectId.
{
  "error": {
    "code": "INVALID_BROADCAST_ID",
    "message": "Bad Request"
  }
}

404 Not Found

The broadcast does not exist or belongs to another tenant.
{
  "error": {
    "code": "BROADCAST_NOT_FOUND",
    "message": "Not Found"
  }
}

401 / 403

Standard auth and scope errors.

Polling pattern

To wait for a broadcast to finish from your integration:
import os, time, requests

def wait_broadcast(broadcast_id: str, timeout: int = 600) -> dict:
    start = time.monotonic()
    headers = {"Authorization": f"Bearer {os.environ['KEEBAI_API_TOKEN']}"}
    while time.monotonic() - start < timeout:
        resp = requests.get(
            f"https://api.keebai.com/v1/messages/bulk/{broadcast_id}",
            headers=headers, timeout=10,
        )
        resp.raise_for_status()
        data = resp.json()
        if data["status"] in ("COMPLETED", "FAILED", "CANCELLED"):
            return data
        time.sleep(5)
    raise TimeoutError(f"Broadcast {broadcast_id} did not finish in {timeout}s")
Use a reasonable sleep (≥5s) between polls to avoid burning through your rate limit. For large campaigns (>1000 recipients), poll every 30s.

Authorizations

Authorization
string
header
required

Personal Access Token con prefijo kbai_pk_. Generar desde el portal con permiso developer.manage_tokens.

Path Parameters

broadcastId
string
required

Response

200 - application/json
broadcast_id
string
required
status
string
required
total_recipients
number
required
sent
number
required
failed
number
required
pending
number
required
started_at
string | null
completed_at
string | null