Message status and history
Track queued messages until they are sent or failed.
Status lifecycle
Every send returns a `message_id`. Store that ID with your own order, user, ticket, or notification record.
The status endpoint returns sender, receiver, timestamps, attempt count, WhatsApp message ID when available, and the latest error message when delivery fails.
`wamid` is the WhatsApp-side message ID. It is usually null while a message is queued and can remain null when delivery fails before WhatsApp accepts the message.
Endpoint reference
Use the same API key used to send the message. A service key can also read status for admin workflows.
/api/messages/{message_id}Return current delivery status and debug fields for a message.
| Parameter | Type | Description |
|---|---|---|
x-api-keyrequired | header | API key that can access the message workspace. |
message_idrequired | path uuid | Message ID returned by a send endpoint. |
{
"message_id": "2b7a0bd5-1a0d-4e6c-85b1-a7f44f92dfb0",
"workspace_id": "f2aa1d49-9f4b-4f37-9918-d8d8f13fb530",
"sender_id": "9f4b5d4c-0000-4000-9000-123456789abc",
"api_client_id": "38b7bbd3-0631-4ea1-a93b-09d560a645d3",
"receiver_number": "212612345678",
"message_text": "Your appointment is confirmed.",
"status": "sent",
"wamid": "wamid.HBgM...",
"source_system": "appointments",
"source_reference": "booking_1042",
"error_message": null,
"attempts": 1,
"queued_at": "2026-06-29T16:12:01.000Z",
"sent_at": "2026-06-29T16:12:04.000Z",
"failed_at": null,
"created_at": "2026-06-29T16:12:01.000Z"
}Polling workflow
Use polling when webhooks are not configured or when the user is actively waiting for a result. For background reconciliation, prefer webhooks.
Do not poll forever. Store the last known status and move old queued messages into an operator review state if they do not change after your business timeout.
async function waitForMessage(messageId: string) {
for (let attempt = 0; attempt < 12; attempt += 1) {
const response = await fetch(`${process.env.HOOKMESSAGE_BASE_URL}/api/messages/${messageId}`, {
headers: { "x-api-key": process.env.HOOKMESSAGE_API_KEY! },
});
const status = await response.json();
if (status.status === "sent" || status.status === "failed") {
return status;
}
await new Promise((resolve) => setTimeout(resolve, attempt < 3 ? 5000 : 15000));
}
return { status: "review_required", message_id: messageId };
}Need help?
Use Book Integration Help if you want setup help for OTP or automated customer messaging.
Next steps
Quickstart
A practical path from empty workspace to a working server-side integration.
Authentication and access
HookMessage separates customer API keys, dashboard sessions, and internal platform access.
Workspaces
A workspace is the tenant boundary for every customer resource.
Senders and sessions
A sender is the WhatsApp number used to deliver messages for a workspace.