Messages
Send messages and read their status.
Everything you send goes through one endpoint, POST /messages. You choose a type, put the content under a key with the same name, and follow what happens through message.* events.
How it works: Sending messagesThe 24-hour window · Text · Media · Buttons, lists and links · Location, contact cards and reactions · Replies, read receipts and typing · What happens after you send · Instagram and Messenger · Which number sends
The 24-hour window#
WhatsApp decides what you may send by one rule:
- Within 24 hours of the customer's last message, the conversation is open: send any type, free-form.
- Otherwise, only an approved template is delivered. Anything else is refused with
window_closedbefore it reaches WhatsApp, so you are never charged for a message that could not arrive.
A template that the customer answers reopens the window. GET /conversations/{id} tells you when it closes (reply_window_expires_at).
Text#
{ "to": "+966501234567", "type": "text", "text": { "body": "أهلًا سارة! طلبك جاهز 🎉", "preview_url": true } }Up to 4,096 characters. preview_url shows a preview of the first link.
Media#
Images, video, audio, documents and stickers come from a public https:// link WhatsApp downloads, or from a file you uploaded once with POST /media:
{ "to": "+966501234567", "type": "document", "document": { "media_id": "med_381", "filename": "invoice-10482.pdf", "caption": "فاتورتك" } }| Type | Formats | Largest | Caption |
|---|---|---|---|
image | JPEG, PNG | 5 MB | yes |
video | MP4, 3GPP | 16 MB | yes |
audio | AAC, MP4, MPEG, AMR, OGG/Opus | 16 MB | no |
document | any file | 100 MB | yes, plus filename |
sticker | WebP 512×512 | 100 KB (500 KB animated) | no |
An upload is checked against these limits when you upload it, so a file that WhatsApp would reject never gets as far as a send.
Buttons, lists and links#
interactive messages are answered with a tap. The customer's choice comes back as a message.received event of type interactive, carrying the id you set: route on it.
{
"to": "+966501234567",
"type": "interactive",
"interactive": {
"type": "button",
"body": "هل تؤكد موعدك غدًا الساعة 4 عصرًا؟",
"buttons": [
{ "id": "confirm_10482", "title": "تأكيد" },
{ "id": "reschedule_10482", "title": "تغيير الموعد" }
]
}
}interactive.type | What the customer sees | Limits |
|---|---|---|
button | Up to 3 reply buttons | title 20 characters, id 256 |
list | A button that opens up to 10 options in sections | 10 rows in total; row title 24, description 72 |
cta_url | One button that opens a link | label 20, https:// only |
location_request | A button to share their location | body only |
Every type takes a body, and all but location_request an optional footer and header (text, or for cta_url an image, video or document link).
Location, contact cards and reactions#
location:latitude,longitude, and optionallynameandaddress.contacts: a list of cards; each needsname.formatted_name, and a phone withwa_idshows a "Message" button.reaction:{"message_id": "imsg_…", "emoji": "👍"}reacts to a message; an emptyemojiremoves it. Reactions are free and do not count as messages.
Replies, read receipts and typing#
- Send
reply_to(amsg_…/imsg_…id or a WhatsApp id) to quote the customer's message in your reply. POST /messages/{id}/readgives the customer blue ticks. Add"typing_indicator": trueto show "typing…" while you prepare the answer (up to 25 seconds, or until you reply).
What happens after you send#
The response comes back as soon as WhatsApp accepts the message, with status: accepted. Then events follow:
| Event | Meaning |
|---|---|
message.sent | WhatsApp sent it |
message.delivered | It reached the customer's phone |
message.read | They opened it (if they share read receipts) |
message.failed | It could not be delivered: error.code is WhatsApp's reason |
Put your own id in reference (an order number, a ticket id): it comes back in the response and in every event, so you never need a lookup table.
Instagram and Messenger#
The same endpoint replies on Instagram and Messenger: set channel and send to the customer id from their message's from. These channels take text, image, video, audio and document, only within 24 hours of the customer's last message, and they have no templates: once the window closes, you can write again only after the customer does.
{ "channel": "instagram", "to": "17841400000000000", "type": "text", "text": { "body": "شكرًا لتواصلك! المقاس متوفر ✨" } }Which number sends#
Leave from out and the message goes from the number the customer last wrote to, or else from your default number. To choose, send from as a number id from GET /numbers, which also tells you whether each number can send right now.
Endpoints
List messages sent through the API
https://api.saei.automize.sa/v1/messages- Scope:
messages:read - Works in test mode
Newest first. Live keys list messages sent with the API; test keys list test-mode messages (sent and simulated inbound).
Query parameters
limitintegeroptionalHow many objects to return, 1 to 100.
cursorstringoptionalThe
next_cursorfrom the previous page.referencestringoptionalOnly the messages you sent with this
reference.tostringoptionalOnly messages to this number (E.164).
Response fields200· A page of messages.
object"list"requireddataarray<Message>requiredChild fields (28)
idstringrequiredUnique id. Opaque: store it as a string of up to 64 characters.
object"message"requiredlivemodebooleanrequireddirectionstringrequiredoutboundfor messages you send,inboundfor customer messages.One of
outboundinboundchannelstringrequiredOne of
whatsappinstagrammessengerfromstring | nulloptionalSender, in E.164 for WhatsApp.
tostring | nulloptionalRecipient, in E.164 for WhatsApp.
typestringrequiredWhat kind of content the message carries.
textobjectoptionalChild fields (1)
bodystringoptional
templateobjectoptionalChild fields (4)
namestringoptionallanguagestringoptionalvariablesobjectoptionalbodystringoptional
imageobjectoptionalMedia messages carry
link(ormedia_id),caption,filenameandmime_typewhen known.videoobjectoptionalaudioobjectoptionaldocumentobjectoptionalstickerobjectoptionallocationobjectoptionalcontactsarrayoptionalinteractiveobjectoptionalWhat you sent (
type,body,buttons…), or for a customer's tap,reply: {id, title}.reactionobjectoptionalstatusstringrequiredaccepted→sent→delivered→read, orfailed. Customer messages arereceived. Status changes arrive as webhook events.One of
acceptedsentdeliveredreadfailedreceivederrorobject | nulloptionalWhy delivery failed, when
statusisfailed.Child fields (3)
codestring | nulloptionaltitlestring | nulloptionalmessagestring | nulloptional
referencestring | nulloptionalYour own reference, echoed back from the send request and in every event.
conversation_idstring | nulloptionalprovider_message_idstring | nulloptionalWhatsApp's own message id (wamid).
contactobject | nulloptionalChild fields (1)
namestring | nulloptional
contextobject | nulloptionalFor a reply, the message being replied to.
Child fields (1)
provider_message_idstringoptional
created_atstring | nullrequiredupdated_atstring | nulloptional
has_morebooleanrequirednext_cursorstring | nullrequired
Errors this can return2
- 422parameter_invalidInvalid parameter
- 429rate_limitedToo many requests
Try it
curl -X GET https://api.saei.automize.sa/v1/messages \
-H "Authorization: Bearer $API_KEY"A page of messages.
{
"object": "list",
"data": [
{
"id": "msg_48213",
"object": "message",
"livemode": false,
"direction": "outbound",
"channel": "whatsapp",
"from": "+966112345678",
"to": "+966501234567",
"type": "text",
"text": {
"body": "string"
},
"template": {
"name": "string",
"language": "string",
"variables": {},
"body": "string"
},
"image": {},
"video": {},
"audio": {},
"document": {},
"sticker": {},
"location": {},
"contacts": [],
"interactive": {},
"reaction": {},
"status": "accepted",
"error": {
"code": "string",
"title": "string",
"message": "string"
},
"reference": "string",
"conversation_id": "string",
"provider_message_id": "string",
"contact": {
"name": "string"
},
"context": {
"provider_message_id": "string"
},
"created_at": "2026-10-01T09:30:00Z",
"updated_at": "2026-10-01T09:30:00Z"
}
],
"has_more": false,
"next_cursor": "string"
}Send a message
https://api.saei.automize.sa/v1/messages- Scope:
messages:send - Simulated in test mode
- Accepts Idempotency-Key
One endpoint for every kind of message: set type and put the content under a key of the same name: text, template, image, video, audio, document, sticker, location, contacts, interactive (reply buttons, lists, link buttons, location requests) or reaction.
- Inside 24 hours of the customer's last message you can send any type.
- Outside that window (or to start a conversation) only an approved
templateis delivered. Anything else returnswindow_closed. - Instagram and Messenger (
channel) take replies only: text and media, inside the 24 hours.
The response comes back as soon as the channel accepts the message (status: accepted). Delivery and read updates arrive as message.* webhook events. With a test key, the message is simulated and never reaches WhatsApp.
Headers
Idempotency-KeystringoptionalAny unique string (a UUID is ideal). Retrying with the same key and body returns the first response instead of acting twice. Remembered for 24 hours.
Request body
Message type
أهلًا سارة! طلبك جاهز للاستلام 🎉
Then these webhook events arrive
- Sent
message.sent - Delivered
message.delivered - Read
message.read
A plain text message. Only inside the 24-hour window after the customer's last message.
channelstringoptionalWhere to send. Instagram and Messenger take replies only (text, image, video, audio, document) within 24 hours of the customer's last message;
tois then the customer id from their message'sfrom.One of
whatsappinstagrammessengertostringrequiredThe customer's phone number in E.164, e.g.
+966501234567. On Instagram / Messenger, the customer id from their message.fromstringoptionalWhich of your numbers sends it: a number id (
num_…) or the number in E.164. Default: the number the customer last wrote to, else your default number.reply_tostringoptionalSend as a reply to this message (a
msg_…/imsg_…id or a WhatsApp wamid).referencestringoptionalYour own id for this message (an order number, a ticket). Returned in the response and in every webhook event about it.
type"text"requiredtextobjectrequiredChild fields (2)
bodystringrequiredThe message text. Up to 4096 characters; Arabic and emoji are fine.
preview_urlbooleanoptionalShow a preview of the first link in the text.
An approved WhatsApp template. The only way to start a conversation or write after the 24-hour window.
channelstringoptionalWhere to send. Instagram and Messenger take replies only (text, image, video, audio, document) within 24 hours of the customer's last message;
tois then the customer id from their message'sfrom.One of
whatsappinstagrammessengertostringrequiredThe customer's phone number in E.164, e.g.
+966501234567. On Instagram / Messenger, the customer id from their message.fromstringoptionalWhich of your numbers sends it: a number id (
num_…) or the number in E.164. Default: the number the customer last wrote to, else your default number.reply_tostringoptionalSend as a reply to this message (a
msg_…/imsg_…id or a WhatsApp wamid).referencestringoptionalYour own id for this message (an order number, a ticket). Returned in the response and in every webhook event about it.
type"template"requiredtemplateobjectrequiredChild fields (4)
namestringoptionalThe template's name, as approved by WhatsApp.
languagestringoptionalLanguage code, e.g.
aroren_US. Required when the name exists in several languages.idstringoptionalThe template id (
tpl_…), instead of name + language.variablesobjectoptionalValues for the placeholders:
body(in order: {{1}}, {{2}}…),header_text,header_media_link, andbuttonsby index (url_suffix,coupon_code,payload).Child fields (4)
bodyarray<string>optionalheader_textstringoptionalheader_media_linkstringoptionalbuttonsobjectoptional
consent_confirmedbooleanoptionalRequired as
trueto send a non-authentication template to a contact who has not agreed to receive business messages. Each confirmation is recorded in the audit log.
A JPEG or PNG image, up to 5 MB.
channelstringoptionalWhere to send. Instagram and Messenger take replies only (text, image, video, audio, document) within 24 hours of the customer's last message;
tois then the customer id from their message'sfrom.One of
whatsappinstagrammessengertostringrequiredThe customer's phone number in E.164, e.g.
+966501234567. On Instagram / Messenger, the customer id from their message.fromstringoptionalWhich of your numbers sends it: a number id (
num_…) or the number in E.164. Default: the number the customer last wrote to, else your default number.reply_tostringoptionalSend as a reply to this message (a
msg_…/imsg_…id or a WhatsApp wamid).referencestringoptionalYour own id for this message (an order number, a ticket). Returned in the response and in every webhook event about it.
type"image"requiredimageobjectrequiredChild fields (3)
linkstringoptionalA public https:// URL WhatsApp downloads the file from. Send
linkormedia_id.media_idstringoptionalA file you uploaded with
POST /v1/media(med_…).captionstringoptionalText shown under the file.
An MP4 or 3GPP video, up to 16 MB.
channelstringoptionalWhere to send. Instagram and Messenger take replies only (text, image, video, audio, document) within 24 hours of the customer's last message;
tois then the customer id from their message'sfrom.One of
whatsappinstagrammessengertostringrequiredThe customer's phone number in E.164, e.g.
+966501234567. On Instagram / Messenger, the customer id from their message.fromstringoptionalWhich of your numbers sends it: a number id (
num_…) or the number in E.164. Default: the number the customer last wrote to, else your default number.reply_tostringoptionalSend as a reply to this message (a
msg_…/imsg_…id or a WhatsApp wamid).referencestringoptionalYour own id for this message (an order number, a ticket). Returned in the response and in every webhook event about it.
type"video"requiredvideoobjectrequiredChild fields (3)
linkstringoptionalA public https:// URL WhatsApp downloads the file from. Send
linkormedia_id.media_idstringoptionalA file you uploaded with
POST /v1/media(med_…).captionstringoptionalText shown under the file.
An audio file (AAC, MP4, MPEG, AMR, OGG/Opus), up to 16 MB. No caption.
channelstringoptionalWhere to send. Instagram and Messenger take replies only (text, image, video, audio, document) within 24 hours of the customer's last message;
tois then the customer id from their message'sfrom.One of
whatsappinstagrammessengertostringrequiredThe customer's phone number in E.164, e.g.
+966501234567. On Instagram / Messenger, the customer id from their message.fromstringoptionalWhich of your numbers sends it: a number id (
num_…) or the number in E.164. Default: the number the customer last wrote to, else your default number.reply_tostringoptionalSend as a reply to this message (a
msg_…/imsg_…id or a WhatsApp wamid).referencestringoptionalYour own id for this message (an order number, a ticket). Returned in the response and in every webhook event about it.
type"audio"requiredaudioobjectrequiredChild fields (2)
linkstringoptionalA public https:// URL WhatsApp downloads the file from. Send
linkormedia_id.media_idstringoptionalA file you uploaded with
POST /v1/media(med_…).
Any file up to 100 MB, e.g. a PDF invoice.
channelstringoptionalWhere to send. Instagram and Messenger take replies only (text, image, video, audio, document) within 24 hours of the customer's last message;
tois then the customer id from their message'sfrom.One of
whatsappinstagrammessengertostringrequiredThe customer's phone number in E.164, e.g.
+966501234567. On Instagram / Messenger, the customer id from their message.fromstringoptionalWhich of your numbers sends it: a number id (
num_…) or the number in E.164. Default: the number the customer last wrote to, else your default number.reply_tostringoptionalSend as a reply to this message (a
msg_…/imsg_…id or a WhatsApp wamid).referencestringoptionalYour own id for this message (an order number, a ticket). Returned in the response and in every webhook event about it.
type"document"requireddocumentobjectrequiredChild fields (4)
linkstringoptionalA public https:// URL WhatsApp downloads the file from. Send
linkormedia_id.media_idstringoptionalA file you uploaded with
POST /v1/media(med_…).captionstringoptionalText shown under the file.
filenamestringoptionalThe file name the customer sees, e.g.
invoice-10482.pdf.
A WebP sticker, 512×512, up to 100 KB (500 KB animated). WhatsApp only.
channelstringoptionalWhere to send. Instagram and Messenger take replies only (text, image, video, audio, document) within 24 hours of the customer's last message;
tois then the customer id from their message'sfrom.One of
whatsappinstagrammessengertostringrequiredThe customer's phone number in E.164, e.g.
+966501234567. On Instagram / Messenger, the customer id from their message.fromstringoptionalWhich of your numbers sends it: a number id (
num_…) or the number in E.164. Default: the number the customer last wrote to, else your default number.reply_tostringoptionalSend as a reply to this message (a
msg_…/imsg_…id or a WhatsApp wamid).referencestringoptionalYour own id for this message (an order number, a ticket). Returned in the response and in every webhook event about it.
type"sticker"requiredstickerobjectrequiredChild fields (2)
linkstringoptionalA public https:// URL WhatsApp downloads the file from. Send
linkormedia_id.media_idstringoptionalA file you uploaded with
POST /v1/media(med_…).
A pin on the map, e.g. your branch.
channelstringoptionalWhere to send. Instagram and Messenger take replies only (text, image, video, audio, document) within 24 hours of the customer's last message;
tois then the customer id from their message'sfrom.One of
whatsappinstagrammessengertostringrequiredThe customer's phone number in E.164, e.g.
+966501234567. On Instagram / Messenger, the customer id from their message.fromstringoptionalWhich of your numbers sends it: a number id (
num_…) or the number in E.164. Default: the number the customer last wrote to, else your default number.reply_tostringoptionalSend as a reply to this message (a
msg_…/imsg_…id or a WhatsApp wamid).referencestringoptionalYour own id for this message (an order number, a ticket). Returned in the response and in every webhook event about it.
type"location"requiredlocationobjectrequiredChild fields (4)
latitudenumberrequiredlongitudenumberrequirednamestringoptionalThe place's name, e.g.
Olaya branch.addressstringoptional
One or more contact cards the customer can save with one tap.
channelstringoptionalWhere to send. Instagram and Messenger take replies only (text, image, video, audio, document) within 24 hours of the customer's last message;
tois then the customer id from their message'sfrom.One of
whatsappinstagrammessengertostringrequiredThe customer's phone number in E.164, e.g.
+966501234567. On Instagram / Messenger, the customer id from their message.fromstringoptionalWhich of your numbers sends it: a number id (
num_…) or the number in E.164. Default: the number the customer last wrote to, else your default number.reply_tostringoptionalSend as a reply to this message (a
msg_…/imsg_…id or a WhatsApp wamid).referencestringoptionalYour own id for this message (an order number, a ticket). Returned in the response and in every webhook event about it.
type"contacts"requiredcontactsarray<object>requiredChild fields (6)
nameobjectrequiredChild fields (3)
formatted_namestringrequiredfirst_namestringoptionallast_namestringoptional
phonesarray<object>optionalChild fields (3)
phonestringrequiredtypestringoptionalOne of
CELLMAINIPHONEHOMEWORKwa_idstringoptionalThe number's WhatsApp id (digits). Adds a "Message" button to the card.
emailsarray<object>optionalChild fields (2)
emailstringrequiredtypestringoptionalOne of
HOMEWORK
orgobjectoptionalChild fields (3)
companystringoptionaldepartmentstringoptionaltitlestringoptional
urlsarray<object>optionalChild fields (2)
urlstringrequiredtypestringoptionalOne of
HOMEWORK
birthdaystringoptional
Messages the customer answers with a tap: up to 3 reply buttons, a list of up to 10 options, a cta_url button that opens a link, or a location_request. Each tap arrives as a message.received event of type interactive carrying the id you chose.
channelstringoptionalWhere to send. Instagram and Messenger take replies only (text, image, video, audio, document) within 24 hours of the customer's last message;
tois then the customer id from their message'sfrom.One of
whatsappinstagrammessengertostringrequiredThe customer's phone number in E.164, e.g.
+966501234567. On Instagram / Messenger, the customer id from their message.fromstringoptionalWhich of your numbers sends it: a number id (
num_…) or the number in E.164. Default: the number the customer last wrote to, else your default number.reply_tostringoptionalSend as a reply to this message (a
msg_…/imsg_…id or a WhatsApp wamid).referencestringoptionalYour own id for this message (an order number, a ticket). Returned in the response and in every webhook event about it.
type"interactive"requiredinteractiveobjectrequiredChild fields (9)
typestringrequiredOne of
buttonlistcta_urllocation_requestheaderobjectoptionalOptional. Reply buttons and lists take a
textheader; a URL button can also show animage,videoordocumentfrom alink.Child fields (3)
typestringrequiredOne of
textimagevideodocumenttextstringoptionallinkstringoptional
bodystringrequiredThe message text. Up to 1024 characters (4096 for a list).
footerstringoptionalbuttonsarray<object>optionalFor
button: 1–3 buttons.id(up to 256 characters) comes back to you when tapped;title(up to 20) is what the customer sees.Child fields (2)
idstringrequiredtitlestringrequired
buttonstringoptionalFor
list: the label of the button that opens the list.sectionsarray<object>optionalFor
list: 1–10 sections, at most 10 rows in total. With more than one section, each needs atitle.Child fields (2)
titlestringoptionalrowsarray<object>requiredChild fields (3)
idstringrequiredtitlestringrequireddescriptionstringoptional
display_textstringoptionalFor
cta_url: the button label.urlstringoptionalFor
cta_url: the https:// page the button opens.
React to a message with an emoji. Send an empty emoji to remove your reaction. Free, and not counted as a message.
channelstringoptionalWhere to send. Instagram and Messenger take replies only (text, image, video, audio, document) within 24 hours of the customer's last message;
tois then the customer id from their message'sfrom.One of
whatsappinstagrammessengertostringrequiredThe customer's phone number in E.164, e.g.
+966501234567. On Instagram / Messenger, the customer id from their message.fromstringoptionalWhich of your numbers sends it: a number id (
num_…) or the number in E.164. Default: the number the customer last wrote to, else your default number.reply_tostringoptionalSend as a reply to this message (a
msg_…/imsg_…id or a WhatsApp wamid).referencestringoptionalYour own id for this message (an order number, a ticket). Returned in the response and in every webhook event about it.
type"reaction"requiredreactionobjectrequiredChild fields (2)
message_idstringrequiredThe message to react to (
imsg_…,msg_…or a WhatsApp wamid).emojistringrequired
Response fields202· Accepted by WhatsApp (or by the simulator, in test mode).
idstringrequiredUnique id. Opaque: store it as a string of up to 64 characters.
object"message"requiredlivemodebooleanrequireddirectionstringrequiredoutboundfor messages you send,inboundfor customer messages.One of
outboundinboundchannelstringrequiredOne of
whatsappinstagrammessengerfromstring | nulloptionalSender, in E.164 for WhatsApp.
tostring | nulloptionalRecipient, in E.164 for WhatsApp.
typestringrequiredWhat kind of content the message carries.
textobjectoptionalChild fields (1)
bodystringoptional
templateobjectoptionalChild fields (4)
namestringoptionallanguagestringoptionalvariablesobjectoptionalbodystringoptional
imageobjectoptionalMedia messages carry
link(ormedia_id),caption,filenameandmime_typewhen known.videoobjectoptionalaudioobjectoptionaldocumentobjectoptionalstickerobjectoptionallocationobjectoptionalcontactsarrayoptionalinteractiveobjectoptionalWhat you sent (
type,body,buttons…), or for a customer's tap,reply: {id, title}.reactionobjectoptionalstatusstringrequiredaccepted→sent→delivered→read, orfailed. Customer messages arereceived. Status changes arrive as webhook events.One of
acceptedsentdeliveredreadfailedreceivederrorobject | nulloptionalWhy delivery failed, when
statusisfailed.Child fields (3)
codestring | nulloptionaltitlestring | nulloptionalmessagestring | nulloptional
referencestring | nulloptionalYour own reference, echoed back from the send request and in every event.
conversation_idstring | nulloptionalprovider_message_idstring | nulloptionalWhatsApp's own message id (wamid).
contactobject | nulloptionalChild fields (1)
namestring | nulloptional
contextobject | nulloptionalFor a reply, the message being replied to.
Child fields (1)
provider_message_idstringoptional
created_atstring | nullrequiredupdated_atstring | nulloptional
Errors this can return21
- 402subscription_inactiveSubscription not active
- 402quota_exceededAllowance used up
- 403api_access_not_in_planAPI not in plan
- 403test_mode_unsupportedNot in test mode
- 422parameter_missingMissing parameter
- 422parameter_invalidInvalid parameter
- 404resource_missingNot found
- 422idempotency_key_reusedIdempotency-Key reused
- 409idempotency_in_progressSame request still running
- 422window_closed24-hour window closed
- 422template_not_foundTemplate not found
- 422template_not_approvedTemplate not approved
- 422template_variables_mismatchWrong template variables
- 409recipient_not_consentedRecipient has not consented
- 422sender_not_configuredNo sending number
- 422sender_not_sendableNumber cannot send
- 422channel_errorWhatsApp rejected it
- 409send_outcome_unknownEarlier attempt may have been sent
- 422channel_not_connectedChannel not connected
- 429rate_limitedToo many requests
- 503platform_pausedSending paused
Try it
curl -X POST https://api.saei.automize.sa/v1/messages \
-H "Authorization: Bearer $API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"to": "+966501234567",
"type": "text",
"text": {
"body": "أهلًا سارة! طلبك جاهز للاستلام 🎉"
},
"reference": "order-10482"
}'Accepted by WhatsApp (or by the simulator, in test mode).
{
"id": "msg_48213",
"object": "message",
"livemode": true,
"direction": "outbound",
"channel": "whatsapp",
"from": "+966112345678",
"to": "+966501234567",
"type": "text",
"text": {
"body": "أهلًا سارة! طلبك جاهز للاستلام 🎉"
},
"status": "accepted",
"error": null,
"reference": "order-10482",
"conversation_id": "conv_311",
"provider_message_id": "wamid.HBgMOTY2NTAxMjM0NTY3FQIAERgSMEM4",
"created_at": "2026-10-01T09:30:00Z",
"updated_at": "2026-10-01T09:30:00Z"
}Get a message
https://api.saei.automize.sa/v1/messages/{id}- Scope:
messages:read - Works in test mode
A message and its current status. Works for messages you sent (msg_…) and customer messages from webhook events (imsg_…).
Path parameters
idstringrequiredThe object's id.
Response fields200· The message.
idstringrequiredUnique id. Opaque: store it as a string of up to 64 characters.
object"message"requiredlivemodebooleanrequireddirectionstringrequiredoutboundfor messages you send,inboundfor customer messages.One of
outboundinboundchannelstringrequiredOne of
whatsappinstagrammessengerfromstring | nulloptionalSender, in E.164 for WhatsApp.
tostring | nulloptionalRecipient, in E.164 for WhatsApp.
typestringrequiredWhat kind of content the message carries.
textobjectoptionalChild fields (1)
bodystringoptional
templateobjectoptionalChild fields (4)
namestringoptionallanguagestringoptionalvariablesobjectoptionalbodystringoptional
imageobjectoptionalMedia messages carry
link(ormedia_id),caption,filenameandmime_typewhen known.videoobjectoptionalaudioobjectoptionaldocumentobjectoptionalstickerobjectoptionallocationobjectoptionalcontactsarrayoptionalinteractiveobjectoptionalWhat you sent (
type,body,buttons…), or for a customer's tap,reply: {id, title}.reactionobjectoptionalstatusstringrequiredaccepted→sent→delivered→read, orfailed. Customer messages arereceived. Status changes arrive as webhook events.One of
acceptedsentdeliveredreadfailedreceivederrorobject | nulloptionalWhy delivery failed, when
statusisfailed.Child fields (3)
codestring | nulloptionaltitlestring | nulloptionalmessagestring | nulloptional
referencestring | nulloptionalYour own reference, echoed back from the send request and in every event.
conversation_idstring | nulloptionalprovider_message_idstring | nulloptionalWhatsApp's own message id (wamid).
contactobject | nulloptionalChild fields (1)
namestring | nulloptional
contextobject | nulloptionalFor a reply, the message being replied to.
Child fields (1)
provider_message_idstringoptional
created_atstring | nullrequiredupdated_atstring | nulloptional
Errors this can return2
- 404resource_missingNot found
- 429rate_limitedToo many requests
Try it
curl -X GET https://api.saei.automize.sa/v1/messages/msg_48213 \
-H "Authorization: Bearer $API_KEY"The message.
{
"id": "msg_48213",
"object": "message",
"livemode": false,
"direction": "outbound",
"channel": "whatsapp",
"from": "+966112345678",
"to": "+966501234567",
"type": "text",
"text": {
"body": "string"
},
"template": {
"name": "string",
"language": "string",
"variables": {},
"body": "string"
},
"image": {},
"video": {},
"audio": {},
"document": {},
"sticker": {},
"location": {},
"contacts": [],
"interactive": {},
"reaction": {},
"status": "accepted",
"error": {
"code": "string",
"title": "string",
"message": "string"
},
"reference": "string",
"conversation_id": "string",
"provider_message_id": "string",
"contact": {
"name": "string"
},
"context": {
"provider_message_id": "string"
},
"created_at": "2026-10-01T09:30:00Z",
"updated_at": "2026-10-01T09:30:00Z"
}Mark a customer message as read
https://api.saei.automize.sa/v1/messages/{id}/read- Scope:
messages:send - Simulated in test mode
Shows the customer blue ticks on their message (and on everything they sent before it). Add typing_indicator: true to also show "typing…" while you prepare the answer: it lasts up to 25 seconds, or until you reply.
Works on WhatsApp messages you received (imsg_…, from message.received events).
Path parameters
idstringrequiredThe object's id.
Request body
typing_indicatorbooleanoptionalAlso show "typing…" to the customer.
Response fields200· The customer now sees the message as read.
object"read_receipt"requiredmessage_idstringrequiredlivemodebooleanrequiredtyping_indicatorbooleanoptional
Errors this can return4
- 404resource_missingNot found
- 422sender_not_configuredNo sending number
- 422channel_errorWhatsApp rejected it
- 429rate_limitedToo many requests
Try it
curl -X POST https://api.saei.automize.sa/v1/messages/msg_48213/read \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"typing_indicator": true
}'The customer now sees the message as read.
{
"object": "read_receipt",
"message_id": "imsg_88213",
"livemode": true,
"typing_indicator": true
}