Messaging

Send customer messages

Queue customer notifications, confirmations, reminders, and support messages.

What the endpoint does

The send endpoint validates the API key, verifies sender ownership, checks plan and sender limits, stores a message record, and queues delivery.

A successful response means the message was accepted into the queue. It does not mean the recipient has already received it. Use the message status endpoint or dashboard history for delivery state.

Endpoint reference

The request must include `receiver_number` and either `message` or `attachment`. Include `sender_id` for an assigned sender, or omit it only when the API key uses random platform sender mode.

Text messages can be up to 4096 characters. Attachments are base64-encoded, limited by the request schema and the decoded storage limit.

POST/api/messages/send

Queue an outbound WhatsApp customer message.

ParameterTypeDescription
x-api-keyrequiredheaderAPI key with the `send_message` role.
sender_iduuidConnected sender assigned to the API key. Omit only for a key configured with random platform sender mode.
receiver_numberrequiredstringDestination phone number.
messagestringMessage body, max 4096 characters. Required unless attachment is present.
attachment.file_namestringAttachment name, max 180 characters.
attachment.mime_typestringAttachment content type, max 120 characters.
attachment.content_base64stringBase64 content, max 10,000,000 characters.
priorityintegerQueue priority from 1 to 10.
source_systemstringIntegration name, max 80 characters.
source_referencestringYour record ID, max 120 characters.
idempotency_keystringDuplicate protection key, max 160 characters.
Request
json
{
  "sender_id": "9f4b5d4c-0000-4000-9000-123456789abc",
  "receiver_number": "212612345678",
  "message": "Your appointment is confirmed for tomorrow at 10:00.",
  "source_system": "appointments",
  "source_reference": "booking_1042",
  "idempotency_key": "booking_1042_confirmation"
}
201 response
json
{
  "message_id": "2b7a0bd5-1a0d-4e6c-85b1-a7f44f92dfb0",
  "workspace_id": "f2aa1d49-9f4b-4f37-9918-d8d8f13fb530",
  "status": "queued",
  "duplicate": false
}

Attachment messages

Use `attachment` when sending an image or document. The backend accepts either raw base64 or a `data:*;base64,` URL and stores the decoded file before delivery.

The request field `attachment.content_base64` accepts up to 10,000,000 characters, but the decoded file must be 5 MB or smaller.

Attachment request
json
{
  "sender_id": "9f4b5d4c-0000-4000-9000-123456789abc",
  "receiver_number": "212612345678",
  "message": "Invoice attached.",
  "attachment": {
    "file_name": "invoice-1042.pdf",
    "mime_type": "application/pdf",
    "content_base64": "JVBERi0xLjQK..."
  },
  "source_system": "billing",
  "source_reference": "invoice_1042",
  "idempotency_key": "invoice:1042:sent"
}

Laravel example

Wrap HookMessage behind a service class so controllers do not know about headers, retry logic, or provider details.

Laravel service
php
use Illuminate\Support\Facades\Http;

$response = Http::baseUrl(config('services.hookmessage.url'))
    ->withHeaders([
        'x-api-key' => config('services.hookmessage.key'),
    ])
    ->post('/api/messages/send', [
        'sender_id' => config('services.hookmessage.sender_id'),
        'receiver_number' => $order->customer_phone,
        'message' => "Your order {$order->number} is confirmed.",
        'source_system' => 'checkout',
        'source_reference' => (string) $order->id,
        'idempotency_key' => "order:{$order->id}:confirmed",
    ]);

$response->throw();
$message = $response->json();

Need help?

Use Book Integration Help if you want setup help for OTP or automated customer messaging.

Next steps