> For the complete documentation index, see [llms.txt](https://docs.360dialog.com/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.360dialog.com/docs/inbox/inbox-api/api-ref/messages.md).

# Messages

You can receive and send WhatsApp messages using following endpoints.

## POST /api/v1/mark\_as\_received/

> Create a new mark, marking messages as received.\
> \
> Every new message will be provided via \`/chats/\` endpoint.\
> In order to no longer receive these messages via above endpoint, you need to mark them as received.\
> \
> \
> You can parse \`/messages/\` endpoint object field \`received\`\
> to determine if a given message still needs to be marked as received.\
> By POSTing data to this endpoint, you create (or update) a mark of \`timestamp\` in relation to a conversation\
> with a contact of given \`customer\_wa\_id\`.\
> \
> \### Recommended usage\
> \
> It is recommended to\
> \* use WABA Webhooks\
> \* or to POST to this endpoint whenever you receive a batch of messages using\
> \`/messages/\` endpoint \*\*and\*\* you confirmed the message was received by the user.\
> \
> \### Forwarding messages to your system\
> \
> If you develop some kind of integration of data between systems or simply bridge these messages to other systems,\
> received message mark is useful for determining which Chats have new messages.\
> By using \`/chats/\` endpoint you can quickly determine which contacts\
> have new, unreceived messages. But to keep this endpoint up to date, you need to create received message marks.\
> \
> \### Instant mark\
> \
> Messages propagated to a User via WABA Webhook successfully (200 OK status code)\
> are automatically marked as received by related User.\
> \
> It is also possible to mark messages as received "instantly" when polling them via our API directly.\
> In such case you should use \`mark\_as\_received\` parameter of \`/messages/\` endpoint.\
> \
> If you use mentioned \`mark\_as\_received\` parameter or you\
> configured a WABA Webhook,\
> usage of the \`/mark\_as\_received/\` endpoint described here is no longer needed.

```json
{"openapi":"3.0.3","info":{"title":"360dialog Inbox API","version":"1.28.0"},"tags":[{"name":"Messages","description":"You can receive and send WhatsApp messages using following endpoints."}],"servers":[{"url":"https://{YOUR_STACK_NAME}.inbox.getchat.360dialog.io/","description":"Your Inbox address. Open the Inbox from the 360dialog Hub to see it.","variables":{"YOUR_STACK_NAME":{"default":"your-stack","description":"The first part of your Inbox address"}}}],"security":[{"tokenAuth":[]}],"components":{"securitySchemes":{"tokenAuth":{"type":"apiKey","in":"header","name":"Authorization","description":"A user token, sent as `Token <token>`. Create a user in the admin panel (group App integration) and get its token from `POST /api/v1/auth/token/`. The channel API key (`D360-Api-Key`) is not supported."}},"schemas":{"ReceivedMessageMark":{"type":"object","properties":{"timestamp":{"type":"integer","description":"A timestamp of the latest message that was received by the User calling this API.\n\nThis API cannot mark messages as received for timestamps that are in the future. The message must be first stored in the Inbox in order to mark it as received in the Inbox and then mark as read in WhatsApp. Make sure to not use current timestamp from your local clock as it might be off with the Inbox server clock. The best idea is to use only timestamps from incoming message payload. Only then you can avoid race conditions of marking messages as received while not (yet) receiving them."},"customer_wa_id":{"type":"string","description":"WhatsApp ID of the message sender"}},"required":["customer_wa_id","timestamp"]},"MarkAsReceivedMessage452Response":{"type":"object","properties":{"reason":{"type":"string"},"timestamp":{"type":"number","format":"double"},"server_timestamp":{"type":"number","format":"double"}},"required":["reason","server_timestamp","timestamp"]},"MarkAsReceivedMessage453Response":{"type":"object","properties":{"reason":{"type":"string"}},"required":["reason"]}}},"paths":{"/api/v1/mark_as_received/":{"post":{"operationId":"createReceivedMessageMark","description":"Create a new mark, marking messages as received.\n\nEvery new message will be provided via `/chats/` endpoint.\nIn order to no longer receive these messages via above endpoint, you need to mark them as received.\n\n\nYou can parse `/messages/` endpoint object field `received`\nto determine if a given message still needs to be marked as received.\nBy POSTing data to this endpoint, you create (or update) a mark of `timestamp` in relation to a conversation\nwith a contact of given `customer_wa_id`.\n\n### Recommended usage\n\nIt is recommended to\n* use WABA Webhooks\n* or to POST to this endpoint whenever you receive a batch of messages using\n`/messages/` endpoint **and** you confirmed the message was received by the user.\n\n### Forwarding messages to your system\n\nIf you develop some kind of integration of data between systems or simply bridge these messages to other systems,\nreceived message mark is useful for determining which Chats have new messages.\nBy using `/chats/` endpoint you can quickly determine which contacts\nhave new, unreceived messages. But to keep this endpoint up to date, you need to create received message marks.\n\n### Instant mark\n\nMessages propagated to a User via WABA Webhook successfully (200 OK status code)\nare automatically marked as received by related User.\n\nIt is also possible to mark messages as received \"instantly\" when polling them via our API directly.\nIn such case you should use `mark_as_received` parameter of `/messages/` endpoint.\n\nIf you use mentioned `mark_as_received` parameter or you\nconfigured a WABA Webhook,\nusage of the `/mark_as_received/` endpoint described here is no longer needed.","tags":["Messages"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReceivedMessageMark"}},"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/ReceivedMessageMark"}},"multipart/form-data":{"schema":{"$ref":"#/components/schemas/ReceivedMessageMark"}}},"required":true},"responses":{"200":{"description":"No response body"},"452":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarkAsReceivedMessage452Response"}}},"description":"Field timestamp value is too far in the future. This API cannot mark messages as received for timestamps that are in the future. The message must be first stored in the Inbox in order to mark it as received in the Inbox and then mark as read in WhatsApp. Make sure to not use current timestamp from your local clock as it might be off with the Inbox server clock. The best idea is to use only timestamps from incoming message payload. Only then you can avoid race conditions of marking messages as received while not (yet) receiving them."},"453":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarkAsReceivedMessage453Response"}}},"description":"Contact of given customer_wa_id does not exist"}}}}}}
```

## GET /api/v1/messages/

> A wrapper of \`messages\` object of\
> \[Inbound Notifications from WhatsApp Business API]\(<https://developers.facebook.com/docs/whatsapp/api/webhooks/inbound)\\>
> (WhatsApp).\
> \
> This object field \`waba\_payload\` contains exactly the same data as specified in WhatsApp Business API.\
> \
> This endpoint is useful for loading messages into a view. Example use cases:\
> \
> \* Message view is loaded for the first time\
> \* Contact message history is loaded or is scrolled\
> \
> To get the number of new messages for all contacts, see \`chats\` endpoint.\
> \
> Messages are ordered from newest to oldest.\
> \
> \### Recommended usage\
> \
> You can use \`limit\` and \`offset\` query parameters to access each page, but it is often advised to use \`before\_time\`\
> instead of \`offset\`.\
> \
> For example, if you only need to get most recent 20 messages, you will use:\
> \
> \`\`\`\
> /api/v1/messages/?limit=20\
> \`\`\`\
> \
> But if you need to read the history of 20 messages before, you should use \`before\_time\` equal to the timestamp\
> of the last (20th) message you got before:\
> \
> \`\`\`\
> /api/v1/messages/?limit=20\&before\_time=1234567890\
> \`\`\`\
> \
> As a result, you will get up to 20 messages that were sent before previous 20 messages.\
> \
> Using \`before\_time\` instead of \`offset\` is advised because it is possible you will get new messages when you browse\
> your paginated history of messages. Since messages are ordered from newest to oldest, \`offset\` based pagination\
> is changing each time you receive a new message from a contact. Using \`before\_time\` solves this problem.

````json
{"openapi":"3.0.3","info":{"title":"360dialog Inbox API","version":"1.28.0"},"tags":[{"name":"Messages","description":"You can receive and send WhatsApp messages using following endpoints."}],"servers":[{"url":"https://{YOUR_STACK_NAME}.inbox.getchat.360dialog.io/","description":"Your Inbox address. Open the Inbox from the 360dialog Hub to see it.","variables":{"YOUR_STACK_NAME":{"default":"your-stack","description":"The first part of your Inbox address"}}}],"security":[{"tokenAuth":[]}],"components":{"securitySchemes":{"tokenAuth":{"type":"apiKey","in":"header","name":"Authorization","description":"A user token, sent as `Token <token>`. Create a user in the admin panel (group App integration) and get its token from `POST /api/v1/auth/token/`. The channel API key (`D360-Api-Key`) is not supported."}},"schemas":{"PaginatedRetrieveMessageList":{"type":"object","required":["count","results"],"properties":{"count":{"type":"integer"},"next":{"type":"string","nullable":true,"format":"uri"},"previous":{"type":"string","nullable":true,"format":"uri"},"results":{"type":"array","items":{"$ref":"#/components/schemas/RetrieveMessage"}}}},"RetrieveMessage":{"type":"object","properties":{"id":{"type":"string","description":"Internal Inbox Message ID"},"waba_payload":{"description":"See [Inbound Notifications from WhatsApp Business API](https://developers.facebook.com/docs/whatsapp/api/webhooks/inbound)"},"waba_statuses":{"allOf":[{"$ref":"#/components/schemas/WabaMessageStatuses"}],"description":"Timestamps of all statuses of the message"},"contact":{"allOf":[{"$ref":"#/components/schemas/Person"}],"description":"Who are we talking to"},"from_us":{"type":"boolean","readOnly":true,"title":"From us?","description":"Allows to easily implement different display for messages sent by us or by customer."},"received":{"type":"boolean","default":false,"description":"Tells if this message was marked as received by you (currently logged in user)"},"sender":{"allOf":[{"$ref":"#/components/schemas/User"}],"description":"Who is talking on our behalf\n\n`null` if this is an incoming message."},"before_time":{"type":"integer"},"since_time":{"type":"integer"},"customer_wa_id":{"type":"string","readOnly":true,"title":"Customer WhatsApp id","description":"**Deprecated**"},"tags":{"type":"array","items":{"$ref":"#/components/schemas/Tagging"},"default":[],"description":"Tags assigned to this Message"},"chat_tags":{"type":"array","items":{"$ref":"#/components/schemas/Tagging"},"default":[],"description":"Tags assigned to the Chat this Message belongs to"},"sent_by_mba":{"type":"boolean","readOnly":true,"title":"Sent by Meta Business Agent","description":"This message was sent on the business's behalf by Meta Business Agent (the copy arrived on the `standby` webhook field). Only set when `from_us` is `true`; distinguishes AI messages from ones sent by inbox users or automation."}},"required":["contact","customer_wa_id","from_us","id","sent_by_mba","waba_payload","waba_statuses"]},"WabaMessageStatuses":{"type":"object","properties":{"sent":{"type":"number","format":"double","nullable":true},"delivered":{"type":"number","format":"double","nullable":true},"read":{"type":"number","format":"double","nullable":true}}},"Person":{"type":"object","properties":{"wa_id":{"type":"string","title":"WhatsApp id","description":"WhatsApp ID — either a phone number in canonical form (e.g. 48123123123) or a Business-Scoped User ID (e.g. US.13491208655302741918) for users who have hidden their phone number.","pattern":"^([A-Z]{2}\\.(ENT\\.)?[a-zA-Z0-9]+|[0-9]+)$","maxLength":200},"bsuid":{"type":"string","readOnly":true,"nullable":true,"title":"Business-Scoped User ID","description":"Business-Scoped User ID for this contact. Populated from the webhook's `user_id` field. Stable across phone number changes for the same user-portfolio pair, so this is the most reliable long-term identifier."},"phone_number":{"type":"string","readOnly":true,"nullable":true,"description":"Phone number when known. Equals `wa_id` for phone-primary contacts. For BSUID-primary contacts (where `wa_id` is a BSUID), populated when WhatsApp shares the phone number — e.g. recent interaction within the last 30 days, or via Contact Book."},"waba_payload":{"$ref":"#/components/schemas/WabaPayloadContact"},"initials":{"type":"string","description":"Contact user name initials used for display when avatar image is missing"},"last_message_timestamp":{"type":"number","format":"double","nullable":true,"description":"[POSIX timestamp](https://en.wikipedia.org/wiki/Unix_time) of last message that was sent by this contact. It is the floor of the customer care messaging window: a non-template message can always be delivered for some time after the customer last wrote to your business, and Meta may keep the window open for longer — see `messaging_window_expires_at`. Read more at WhatsApp Business API docs [Messages Cut-off Control](https://developers.facebook.com/docs/whatsapp/api/messages#cut-off-control)."},"messaging_window_expires_at":{"type":"number","format":"double","readOnly":true,"description":"[POSIX timestamp](https://en.wikipedia.org/wiki/Unix_time) after which a non-template message to this contact is rejected with HTTP 453. Derived from what Meta reported for this conversation, the customer's last message, and — for click-to-WhatsApp chats we have not replied to yet — the ad referral. Never assume a fixed duration: read this value."},"messaging_window_origin":{"type":"string","readOnly":true,"nullable":true,"description":"`conversation.origin.type` reported by Meta alongside `messaging_window_expires_at` — what opened the conversation (e.g. `service`, `marketing`, `utility`, `authentication`, or `referral_conversion` for a click-to-WhatsApp ad)."},"resolved":{"type":"boolean","description":"Whether this chat is considered resolved by the assigned agent. Can automatically be set to false if contact keeps sending messages."}},"required":["bsuid","initials","messaging_window_expires_at","messaging_window_origin","phone_number","wa_id","waba_payload"]},"WabaPayloadContact":{"type":"object","properties":{"profile":{"$ref":"#/components/schemas/WabaPayloadProfile"},"wa_id":{"type":"string"}},"required":["profile","wa_id"]},"WabaPayloadProfile":{"type":"object","properties":{"name":{"type":"string"}},"required":["name"]},"User":{"type":"object","properties":{"url":{"type":"string","format":"uri","readOnly":true},"id":{"type":"integer","readOnly":true},"username":{"type":"string","description":"Username that is used in combination with password during login.\n\nOnly alphanumeric characters are allowed (A-Z, a-z, 0-9)."},"first_name":{"type":"string","maxLength":150},"last_name":{"type":"string","maxLength":150},"email":{"type":"string","format":"email","description":"E-mail address of this new user.\n\n"},"profile":{"allOf":[{"$ref":"#/components/schemas/UserProfile"}],"description":"Optional field used to create app users and additional admin users"},"groups":{"type":"array","items":{"$ref":"#/components/schemas/GroupMember"},"readOnly":true,"description":"List of group objects the user belongs to (read-only)"},"group_ids":{"type":"array","items":{"type":"integer","writeOnly":true},"writeOnly":true,"description":"List of group IDs to assign to the user (write-only)"},"permissions":{"$ref":"#/components/schemas/Permissions"},"assigned_wa_ids":{"type":"array","items":{"type":"string"},"readOnly":true}},"required":["assigned_wa_ids","email","groups","id","permissions","url","username"]},"UserProfile":{"type":"object","properties":{"role":{"allOf":[{"$ref":"#/components/schemas/RoleEnum"}],"description":"<p>Possible values:<br>    * <code>user</code> (<strong>User</strong>) - can do everything that isn't marked as admin only in API documentation<br>    * <code>admin</code> (<strong>Admin</strong>) - can use all available API endpoints and has Inbox admin panel access<br>    * <code>app</code> (<strong>App integration</strong>) - can do everything regular users have access too, but has no access to inbox web frontend</p>\n\n* `user` - Regular user\n* `admin` - Admin\n* `app` - App integration"},"is_available":{"type":"boolean","description":"Manual status set by the user to indicate availability for communication."}}},"RoleEnum":{"enum":["user","admin","app"],"type":"string","description":"* `user` - Regular user\n* `admin` - Admin\n* `app` - App integration"},"GroupMember":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"}},"required":["id","name"]},"Permissions":{"type":"object","properties":{"can_use_tags":{"type":"boolean","description":"Uncheck this to disable tagging for related Users completely."},"can_read_chats":{"allOf":[{"$ref":"#/components/schemas/CanReadChatsEnum"}],"description":"<p>Possible values:<br><code>all</code> - User can read from All Chats<br>\n<code>group</code> - User can read from Only Chats assigned to User's Groups<br>\n<code>user</code> - User can read from Only Chats assigned to User directly<br>\n<code>none</code> - User can read from No Chats</p>\n\n* `all` - All Chats\n* `group` - Only Chats assigned to User's Groups\n* `user` - Only Chats assigned to User directly\n* `none` - No Chats"},"can_write_to_chats":{"allOf":[{"$ref":"#/components/schemas/CanWriteToChatsEnum"}],"description":"<p>Possible values:<br><code>all</code> - User can write to All Chats<br>\n<code>group</code> - User can write to Only Chats assigned to User's Groups<br>\n<code>user</code> - User can write to Only Chats assigned to User directly<br>\n<code>none</code> - User can write to No Chats</p>\n\n* `all` - All Chats\n* `group` - Only Chats assigned to User's Groups\n* `user` - Only Chats assigned to User directly\n* `none` - No Chats"}}},"CanReadChatsEnum":{"enum":["all","group","user","none"],"type":"string","description":"* `all` - All Chats\n* `group` - Only Chats assigned to User's Groups\n* `user` - Only Chats assigned to User directly\n* `none` - No Chats"},"CanWriteToChatsEnum":{"enum":["all","group","user","none"],"type":"string","description":"* `all` - All Chats\n* `group` - Only Chats assigned to User's Groups\n* `user` - Only Chats assigned to User directly\n* `none` - No Chats"},"Tagging":{"type":"object","properties":{"name":{"type":"string","description":"Tag object name"},"web_inbox_color":{"type":"string","description":"A Web App related setting - which color to show on the Web App frontend"},"tagging_id":{"type":"integer","readOnly":true,"description":"This tagging relation ID. Used when deleting a Tagging for example."},"id":{"type":"integer","description":"Tag object unique ID"},"extra":{"description":"Tagging extra payload"}},"required":["id","name","tagging_id","web_inbox_color"]}}},"paths":{"/api/v1/messages/":{"get":{"operationId":"listMessages","description":"A wrapper of `messages` object of\n[Inbound Notifications from WhatsApp Business API](https://developers.facebook.com/docs/whatsapp/api/webhooks/inbound)\n(WhatsApp).\n\nThis object field `waba_payload` contains exactly the same data as specified in WhatsApp Business API.\n\nThis endpoint is useful for loading messages into a view. Example use cases:\n\n* Message view is loaded for the first time\n* Contact message history is loaded or is scrolled\n\nTo get the number of new messages for all contacts, see `chats` endpoint.\n\nMessages are ordered from newest to oldest.\n\n### Recommended usage\n\nYou can use `limit` and `offset` query parameters to access each page, but it is often advised to use `before_time`\ninstead of `offset`.\n\nFor example, if you only need to get most recent 20 messages, you will use:\n\n```\n/api/v1/messages/?limit=20\n```\n\nBut if you need to read the history of 20 messages before, you should use `before_time` equal to the timestamp\nof the last (20th) message you got before:\n\n```\n/api/v1/messages/?limit=20&before_time=1234567890\n```\n\nAs a result, you will get up to 20 messages that were sent before previous 20 messages.\n\nUsing `before_time` instead of `offset` is advised because it is possible you will get new messages when you browse\nyour paginated history of messages. Since messages are ordered from newest to oldest, `offset` based pagination\nis changing each time you receive a new message from a contact. Using `before_time` solves this problem.","parameters":[{"in":"query","name":"assigned_group","schema":{"type":"integer"},"description":"Filter only Messages of Chats assigned to specified Group.\n            Skip this param to display all messages currently logged in User has access to.\n            Param value is an integer identifier of the Group.\n            Only Groups the User is member of can be used."},{"in":"query","name":"assigned_to_me","schema":{"type":"boolean"},"description":"Filter only Messages of Chats assigned to currently logged in User.\n            Skip this param or leave default `false` to display all messages User has access to."},{"in":"query","name":"before_time","schema":{"type":"integer"},"description":"[POSIX timestamp](https://en.wikipedia.org/wiki/Unix_time).\n            Returns only messages that are **older** than specified `before_time`.\n            This parameter makes it easy to just pass the timestamp of the last message you have\n            and receive only messages older than related message.\n\n\nThis should be used when implementing scroll of the messages from newest to oldest."},{"in":"query","name":"chat_tag_id","schema":{"type":"integer"},"description":"Filter only Messages of Chats having given tag ID."},{"in":"query","name":"from_us","schema":{"type":"boolean"},"description":"Filter only Messages that are either from us (inbox users and automation) or not."},{"in":"query","name":"limit","schema":{"type":"integer"},"description":"Number of results to return per page."},{"in":"query","name":"mark_as_received","schema":{"type":"integer"},"description":"Mark all returned messages as received by you (logged in user). You need to use either this param or POST to\n            `/mark_as_received/` endpoint to mark messages as received.\n            Marking messages as received by you is needed to generate a proper list of new messages.\n            (You can check how many unread messages there are for each contact with\n            `/chats/` endpoint.)\n            It is required to use one or the other when you implement any kind of indication of new/unread messages\n            or when you simply forward messages to your system in batches and would like to receive only\n            fresh messages on each iteration.\n          "},{"in":"query","name":"offset","schema":{"type":"integer"},"description":"The initial index from which to return the results."},{"in":"query","name":"search","schema":{"type":"string"},"description":"Filter Messages by string query - search for messages containing specified text phrase.\n\n\nThe API will search in following places:\n\n* `text.body` field of `waba_payload` JSON\n\n* `{media_type}.caption` or `{media_type}.filename` of media type message fields:\n  `image`, `document`, `audio`, `video` ,`voice`, `sticker`\"\n\n* `name` field of each Tag in `tags` field of each Message"},{"in":"query","name":"since_time","schema":{"type":"integer"},"description":"[POSIX timestamp](https://en.wikipedia.org/wiki/Unix_time).\n            Returns only messages that are **at the same timestamp or newer** than specified `since_time`.\n\n\nThis should be used when implementing scroll of the messages from oldest to newest."},{"in":"query","name":"wa_id","schema":{"type":"string"},"description":"WhatsApp id of related contact"}],"tags":["Messages"],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedRetrieveMessageList"}}},"description":""},"452":{"content":{"application/json":{"schema":{"type":"object","properties":{"reason":{"type":"string"}}}}},"description":"The contact does not exist"}}}}}}
````

## POST /api/v1/messages/

> Create a new message\
> \
> This object contains selected data that is following specification of\
> \[WhatsApp Business API]\(<https://developers.facebook.com/docs/whatsapp/api/messages).\\>
> \
> The \<u>\`type\`\</u> field determines the type of message. Choosing one of possible types makes related field required.\
> For example, choosing \`"type": "text"\` makes field \`text\` required.\
> \
> If the recipient does not have WhatsApp, the resulting WhatsApp Business API error (WhatsApp Business API Client\
> Error Code 470) will be forwarded to you asynchronously using another channel (e.g. websocket).

```json
{"openapi":"3.0.3","info":{"title":"360dialog Inbox API","version":"1.28.0"},"tags":[{"name":"Messages","description":"You can receive and send WhatsApp messages using following endpoints."}],"servers":[{"url":"https://{YOUR_STACK_NAME}.inbox.getchat.360dialog.io/","description":"Your Inbox address. Open the Inbox from the 360dialog Hub to see it.","variables":{"YOUR_STACK_NAME":{"default":"your-stack","description":"The first part of your Inbox address"}}}],"security":[{"tokenAuth":[]}],"components":{"securitySchemes":{"tokenAuth":{"type":"apiKey","in":"header","name":"Authorization","description":"A user token, sent as `Token <token>`. Create a user in the admin panel (group App integration) and get its token from `POST /api/v1/auth/token/`. The channel API key (`D360-Api-Key`) is not supported."}},"schemas":{"CreateMessage":{"type":"object","properties":{"type":{"$ref":"#/components/schemas/CreateMessageTypeEnum"},"verify_contact":{"type":"boolean","nullable":true,"default":false,"description":"\n**Deprecated parameter**: Will be treated as false regardless of value, as contact verification has been removed from\nWhatsApp side.\n\nSee endpoint description. It has been updated to reflect the new workflow.\n"},"text":{"$ref":"#/components/schemas/MessageText"},"image":{"$ref":"#/components/schemas/CaptionedMedia"},"contacts":{"description":"See [Contact Messages WhatsApp Business API Documentation](https://developers.facebook.com/docs/whatsapp/api/messages/others#contacts-messages)"},"document":{"$ref":"#/components/schemas/MessageDocument"},"hsm":{"description":"**Deprecated:** The `hsm` object has been deprecated with v2.39 of the WhatsApp Business API.See [2.39.1 changelog](https://developers.facebook.com/docs/whatsapp/on-premises/changelog#wa239) and [WhatsApp Business API Documentation](https://developers.facebook.com/docs/whatsapp/on-premises/reference/messages#hsm-object)."},"location":{"description":"See [Location Messages WhatsApp Business API Documentation](https://developers.facebook.com/docs/whatsapp/api/messages/others#locations)"},"sticker":{"$ref":"#/components/schemas/MessageSticker"},"template":{"description":"See [Template Messages WhatsApp Business API Documentation](https://developers.facebook.com/docs/whatsapp/message-templates/creation)"},"audio":{"$ref":"#/components/schemas/MessageMedia"},"video":{"$ref":"#/components/schemas/CaptionedMedia"},"interactive":{"description":"See [`interactive` object in WhatsApp Business API Documentation](https://developers.facebook.com/documentation/business-messaging/whatsapp/reference/whatsapp-business-phone-number/message-api#post-version-phone-number-id-messages)"},"reaction":{"$ref":"#/components/schemas/MessageReaction"},"wa_id":{"type":"string","description":"WhatsApp ID of the message recipient — either a phone number in canonical form (e.g. 48123123123) or a Business-Scoped User ID (e.g. US.13491208655302741918).","pattern":"^([A-Z]{2}\\.(ENT\\.)?[a-zA-Z0-9]+|[0-9]+)$"}},"required":["type","wa_id"]},"CreateMessageTypeEnum":{"enum":["text","image","contacts","document","hsm","location","sticker","template","audio","video","interactive","reaction"],"type":"string","description":"* `text` - text\n* `image` - image\n* `contacts` - contacts\n* `document` - document\n* `hsm` - hsm\n* `location` - location\n* `sticker` - sticker\n* `template` - template\n* `audio` - audio\n* `video` - video\n* `interactive` - interactive\n* `reaction` - reaction"},"MessageText":{"type":"object","properties":{"body":{"type":"string"},"preview_url":{"type":"boolean","description":"Set to true to have the WhatsApp client attempt to render a link preview for the first URL in the body text. URLs must begin with http:// or https://. See: https://developers.facebook.com/docs/whatsapp/cloud-api/messages/text-messages"}},"required":["body"]},"CaptionedMedia":{"type":"object","description":"A media object that has `caption` field\n\nUsed in `document`, `image` and `video` media. Do **not** use with `audio` or `sticker` media.\n\nSee: https://developers.facebook.com/documentation/business-messaging/whatsapp/reference/whatsapp-business-phone-number/message-api#post-version-phone-number-id-messages","properties":{"link":{"type":"string","description":"This needs to be HTTPS URL to one of media uploaded to our API. See creating a new media file"},"mime_type":{"type":"string","description":"Mimetype of the media file. This parameter is optional, but providing it is recommended. It will be required for applications like inbox frontend, to be able to determine file type before it is actually downloaded from the `link`."},"caption":{"type":"string","description":"Caption of the media file"}},"required":["link"]},"MessageDocument":{"type":"object","description":"A media object that has `caption` field\n\nUsed in `document`, `image` and `video` media. Do **not** use with `audio` or `sticker` media.\n\nSee: https://developers.facebook.com/documentation/business-messaging/whatsapp/reference/whatsapp-business-phone-number/message-api#post-version-phone-number-id-messages","properties":{"link":{"type":"string","description":"This needs to be HTTPS URL to one of media uploaded to our API. See creating a new media file"},"mime_type":{"type":"string","description":"Mimetype of the media file. This parameter is optional, but providing it is recommended. It will be required for applications like inbox frontend, to be able to determine file type before it is actually downloaded from the `link`."},"caption":{"type":"string","description":"Caption of the media file. WhatsApp does not display caption to end users when sending a document type of message, but WhatsApp uses the caption field as a fallback when filename field is missing."},"filename":{"type":"string","description":"Describes the filename for the specific document. If not provided, caption field will be used as a fallback."}},"required":["link"]},"MessageSticker":{"type":"object","properties":{"link":{"type":"string","description":"HTTPS link to a sticker file"}},"required":["link"]},"MessageMedia":{"type":"object","description":"Media file common fields\n\n`link` is used in `audio`, `document`, `image`, `sticker` and `video` type of messages.\n\nWe're not using Business API's `id` field, so this makes `link` field always required.\n\nSee: https://developers.facebook.com/documentation/business-messaging/whatsapp/reference/whatsapp-business-phone-number/message-api#post-version-phone-number-id-messages\n\nOptionally we take `mime_type` in addition to what's on Business API side, because incoming messages provide\n`mime_type` in `waba_payload`. This gives consistent payload for applications like inbox frontend, where\nmedia file type can be determined before it is actually downloaded.","properties":{"link":{"type":"string","description":"This needs to be HTTPS URL to one of media uploaded to our API. See creating a new media file"},"mime_type":{"type":"string","description":"Mimetype of the media file. This parameter is optional, but providing it is recommended. It will be required for applications like inbox frontend, to be able to determine file type before it is actually downloaded from the `link`."}},"required":["link"]},"MessageReaction":{"type":"object","properties":{"message_id":{"type":"string","description":"\nWhatsApp message ID of message you want to apply the emoji to.\n\nIf the message you are reacting to is more than 30 days old, doesn't correspond to any message in the conversation, has been deleted, or is itself a reaction message, the reaction message will not be delivered and you will receive a messages webhook with error code 131009.\n","maxLength":300},"emoji":{"type":"string","description":"\nUnicode escape sequence of the emoji, or the emoji itself, to apply to the user message.\nFor example: `\"\\uD83D\\uDE00\"` or `\"😀\"`\n","maxLength":100}},"required":["emoji","message_id"]},"MessageSendSuccessfulResponse":{"type":"object","properties":{"reason":{"type":"string"},"id":{"type":"string","description":"Internal Inbox message ID that was generated when adding Message to queue.\n    You will receive this value as `\"getchat_id\"` in `\"statuses\"` events sent to your webhook(s)."}},"required":["id"]},"MessageWabaErrorResponse":{"type":"object","properties":{"reason":{"type":"string"}},"required":["reason"]}}},"paths":{"/api/v1/messages/":{"post":{"operationId":"createMessage","description":"Create a new message\n\nThis object contains selected data that is following specification of\n[WhatsApp Business API](https://developers.facebook.com/docs/whatsapp/api/messages).\n\nThe <u>`type`</u> field determines the type of message. Choosing one of possible types makes related field required.\nFor example, choosing `\"type\": \"text\"` makes field `text` required.\n\nIf the recipient does not have WhatsApp, the resulting WhatsApp Business API error (WhatsApp Business API Client\nError Code 470) will be forwarded to you asynchronously using another channel (e.g. websocket).","tags":["Messages"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMessage"}},"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/CreateMessage"}},"multipart/form-data":{"schema":{"$ref":"#/components/schemas/CreateMessage"}}},"required":true},"responses":{"200":{"description":"Message sent.\n\n> **DEPRECATED:** This endpoint either replies with **202** status code or other documented codes."},"202":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageSendSuccessfulResponse"}}},"description":"Message is added to the queue and will be sent soon.\n\n> Note that **this doesn't indicate that the message is sent**.\nAwait message \"statuses\" events\nto determine when message is sent, received and read by recipient.\nNote that you need to inspect `\"getchat_id\"` value inside received `\"statuses\"` events,\nin order to be able to relate statuses with outgoing messages."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageWabaErrorResponse"}}},"description":"User error. Please check your request and API response.\n\n> There are various scenarios for 400 status code and the API reply will provide as precise information\non the client-side error as possible. For example, if JSON data is not provided, `\"reason\"` field\nis returned with `\"JSON data not provided\"` as reason value.\nIf there are problems with specific fields, those are denoted with their names in the API response\npayload. Every field can have multiple errors, so those error messages are provided in a list\n(see 400 response examples)."},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageWabaErrorResponse"}}},"description":"You have no permission to send messages to this Chat.\n\n> Check your User account settings. Each User needs to have `permissions` specified -\nif the User can read from or write to Chats."},"423":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageWabaErrorResponse"}}},"description":"Queue is full. Your quota is full of pending messages.\n\n> Your quota is limited (by default) to 1.5M messages stored permanently.\nWhen you reach your quota, the oldest messages in your storage are removed when they are over quota.\nYou can reach your quota by either receiving or sending messages.\nWhen sending, messages are first added to the queue and then they are propagated to WhatsApp.\nIf you are too fast, you might end up with entire quota (by default 1.5 million) of messages\nconsisting of pending messages. This leads to a situation when you no longer can add messages to the\nqueue, because it would remove not-yet-sent messages from your storage.\nNormally, this condition is hard to be met, but can be met easily if your WhatsApp Business API\nendpoint has been blocked by Meta for some reason, or the endpoint has some performance issues."},"453":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageWabaErrorResponse"}}},"description":"Customer care messaging window expired.\n\n> You can message WhatsApp users with session messages only while the customer\ncare messaging window is open. Outside this window, only `template` messages\nare allowed.\n>\n> Do not assume a fixed duration: the window depends on what opened the\nconversation (an ad click lasts considerably longer than an organic message)\nand Meta changes it over time. Read `messaging_window_expires_at` from the\nChat's contact instead."},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageWabaErrorResponse"}}},"description":"The message gateway could not be reached.\n\n> Retry after a few seconds. Read the Chat's messages first if you need to be\ncertain: a request that timed out rather than being refused may have queued\nthe message before the gateway stopped answering."}}}}}}
```

## GET /api/v1/messages/{id}/

> Get a single Message by its Inbox message ID.

```json
{"openapi":"3.0.3","info":{"title":"360dialog Inbox API","version":"1.28.0"},"tags":[{"name":"Messages","description":"You can receive and send WhatsApp messages using following endpoints."}],"servers":[{"url":"https://{YOUR_STACK_NAME}.inbox.getchat.360dialog.io/","description":"Your Inbox address. Open the Inbox from the 360dialog Hub to see it.","variables":{"YOUR_STACK_NAME":{"default":"your-stack","description":"The first part of your Inbox address"}}}],"security":[{"tokenAuth":[]}],"components":{"securitySchemes":{"tokenAuth":{"type":"apiKey","in":"header","name":"Authorization","description":"A user token, sent as `Token <token>`. Create a user in the admin panel (group App integration) and get its token from `POST /api/v1/auth/token/`. The channel API key (`D360-Api-Key`) is not supported."}},"schemas":{"RetrieveMessage":{"type":"object","properties":{"id":{"type":"string","description":"Internal Inbox Message ID"},"waba_payload":{"description":"See [Inbound Notifications from WhatsApp Business API](https://developers.facebook.com/docs/whatsapp/api/webhooks/inbound)"},"waba_statuses":{"allOf":[{"$ref":"#/components/schemas/WabaMessageStatuses"}],"description":"Timestamps of all statuses of the message"},"contact":{"allOf":[{"$ref":"#/components/schemas/Person"}],"description":"Who are we talking to"},"from_us":{"type":"boolean","readOnly":true,"title":"From us?","description":"Allows to easily implement different display for messages sent by us or by customer."},"received":{"type":"boolean","default":false,"description":"Tells if this message was marked as received by you (currently logged in user)"},"sender":{"allOf":[{"$ref":"#/components/schemas/User"}],"description":"Who is talking on our behalf\n\n`null` if this is an incoming message."},"before_time":{"type":"integer"},"since_time":{"type":"integer"},"customer_wa_id":{"type":"string","readOnly":true,"title":"Customer WhatsApp id","description":"**Deprecated**"},"tags":{"type":"array","items":{"$ref":"#/components/schemas/Tagging"},"default":[],"description":"Tags assigned to this Message"},"chat_tags":{"type":"array","items":{"$ref":"#/components/schemas/Tagging"},"default":[],"description":"Tags assigned to the Chat this Message belongs to"},"sent_by_mba":{"type":"boolean","readOnly":true,"title":"Sent by Meta Business Agent","description":"This message was sent on the business's behalf by Meta Business Agent (the copy arrived on the `standby` webhook field). Only set when `from_us` is `true`; distinguishes AI messages from ones sent by inbox users or automation."}},"required":["contact","customer_wa_id","from_us","id","sent_by_mba","waba_payload","waba_statuses"]},"WabaMessageStatuses":{"type":"object","properties":{"sent":{"type":"number","format":"double","nullable":true},"delivered":{"type":"number","format":"double","nullable":true},"read":{"type":"number","format":"double","nullable":true}}},"Person":{"type":"object","properties":{"wa_id":{"type":"string","title":"WhatsApp id","description":"WhatsApp ID — either a phone number in canonical form (e.g. 48123123123) or a Business-Scoped User ID (e.g. US.13491208655302741918) for users who have hidden their phone number.","pattern":"^([A-Z]{2}\\.(ENT\\.)?[a-zA-Z0-9]+|[0-9]+)$","maxLength":200},"bsuid":{"type":"string","readOnly":true,"nullable":true,"title":"Business-Scoped User ID","description":"Business-Scoped User ID for this contact. Populated from the webhook's `user_id` field. Stable across phone number changes for the same user-portfolio pair, so this is the most reliable long-term identifier."},"phone_number":{"type":"string","readOnly":true,"nullable":true,"description":"Phone number when known. Equals `wa_id` for phone-primary contacts. For BSUID-primary contacts (where `wa_id` is a BSUID), populated when WhatsApp shares the phone number — e.g. recent interaction within the last 30 days, or via Contact Book."},"waba_payload":{"$ref":"#/components/schemas/WabaPayloadContact"},"initials":{"type":"string","description":"Contact user name initials used for display when avatar image is missing"},"last_message_timestamp":{"type":"number","format":"double","nullable":true,"description":"[POSIX timestamp](https://en.wikipedia.org/wiki/Unix_time) of last message that was sent by this contact. It is the floor of the customer care messaging window: a non-template message can always be delivered for some time after the customer last wrote to your business, and Meta may keep the window open for longer — see `messaging_window_expires_at`. Read more at WhatsApp Business API docs [Messages Cut-off Control](https://developers.facebook.com/docs/whatsapp/api/messages#cut-off-control)."},"messaging_window_expires_at":{"type":"number","format":"double","readOnly":true,"description":"[POSIX timestamp](https://en.wikipedia.org/wiki/Unix_time) after which a non-template message to this contact is rejected with HTTP 453. Derived from what Meta reported for this conversation, the customer's last message, and — for click-to-WhatsApp chats we have not replied to yet — the ad referral. Never assume a fixed duration: read this value."},"messaging_window_origin":{"type":"string","readOnly":true,"nullable":true,"description":"`conversation.origin.type` reported by Meta alongside `messaging_window_expires_at` — what opened the conversation (e.g. `service`, `marketing`, `utility`, `authentication`, or `referral_conversion` for a click-to-WhatsApp ad)."},"resolved":{"type":"boolean","description":"Whether this chat is considered resolved by the assigned agent. Can automatically be set to false if contact keeps sending messages."}},"required":["bsuid","initials","messaging_window_expires_at","messaging_window_origin","phone_number","wa_id","waba_payload"]},"WabaPayloadContact":{"type":"object","properties":{"profile":{"$ref":"#/components/schemas/WabaPayloadProfile"},"wa_id":{"type":"string"}},"required":["profile","wa_id"]},"WabaPayloadProfile":{"type":"object","properties":{"name":{"type":"string"}},"required":["name"]},"User":{"type":"object","properties":{"url":{"type":"string","format":"uri","readOnly":true},"id":{"type":"integer","readOnly":true},"username":{"type":"string","description":"Username that is used in combination with password during login.\n\nOnly alphanumeric characters are allowed (A-Z, a-z, 0-9)."},"first_name":{"type":"string","maxLength":150},"last_name":{"type":"string","maxLength":150},"email":{"type":"string","format":"email","description":"E-mail address of this new user.\n\n"},"profile":{"allOf":[{"$ref":"#/components/schemas/UserProfile"}],"description":"Optional field used to create app users and additional admin users"},"groups":{"type":"array","items":{"$ref":"#/components/schemas/GroupMember"},"readOnly":true,"description":"List of group objects the user belongs to (read-only)"},"group_ids":{"type":"array","items":{"type":"integer","writeOnly":true},"writeOnly":true,"description":"List of group IDs to assign to the user (write-only)"},"permissions":{"$ref":"#/components/schemas/Permissions"},"assigned_wa_ids":{"type":"array","items":{"type":"string"},"readOnly":true}},"required":["assigned_wa_ids","email","groups","id","permissions","url","username"]},"UserProfile":{"type":"object","properties":{"role":{"allOf":[{"$ref":"#/components/schemas/RoleEnum"}],"description":"<p>Possible values:<br>    * <code>user</code> (<strong>User</strong>) - can do everything that isn't marked as admin only in API documentation<br>    * <code>admin</code> (<strong>Admin</strong>) - can use all available API endpoints and has Inbox admin panel access<br>    * <code>app</code> (<strong>App integration</strong>) - can do everything regular users have access too, but has no access to inbox web frontend</p>\n\n* `user` - Regular user\n* `admin` - Admin\n* `app` - App integration"},"is_available":{"type":"boolean","description":"Manual status set by the user to indicate availability for communication."}}},"RoleEnum":{"enum":["user","admin","app"],"type":"string","description":"* `user` - Regular user\n* `admin` - Admin\n* `app` - App integration"},"GroupMember":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"}},"required":["id","name"]},"Permissions":{"type":"object","properties":{"can_use_tags":{"type":"boolean","description":"Uncheck this to disable tagging for related Users completely."},"can_read_chats":{"allOf":[{"$ref":"#/components/schemas/CanReadChatsEnum"}],"description":"<p>Possible values:<br><code>all</code> - User can read from All Chats<br>\n<code>group</code> - User can read from Only Chats assigned to User's Groups<br>\n<code>user</code> - User can read from Only Chats assigned to User directly<br>\n<code>none</code> - User can read from No Chats</p>\n\n* `all` - All Chats\n* `group` - Only Chats assigned to User's Groups\n* `user` - Only Chats assigned to User directly\n* `none` - No Chats"},"can_write_to_chats":{"allOf":[{"$ref":"#/components/schemas/CanWriteToChatsEnum"}],"description":"<p>Possible values:<br><code>all</code> - User can write to All Chats<br>\n<code>group</code> - User can write to Only Chats assigned to User's Groups<br>\n<code>user</code> - User can write to Only Chats assigned to User directly<br>\n<code>none</code> - User can write to No Chats</p>\n\n* `all` - All Chats\n* `group` - Only Chats assigned to User's Groups\n* `user` - Only Chats assigned to User directly\n* `none` - No Chats"}}},"CanReadChatsEnum":{"enum":["all","group","user","none"],"type":"string","description":"* `all` - All Chats\n* `group` - Only Chats assigned to User's Groups\n* `user` - Only Chats assigned to User directly\n* `none` - No Chats"},"CanWriteToChatsEnum":{"enum":["all","group","user","none"],"type":"string","description":"* `all` - All Chats\n* `group` - Only Chats assigned to User's Groups\n* `user` - Only Chats assigned to User directly\n* `none` - No Chats"},"Tagging":{"type":"object","properties":{"name":{"type":"string","description":"Tag object name"},"web_inbox_color":{"type":"string","description":"A Web App related setting - which color to show on the Web App frontend"},"tagging_id":{"type":"integer","readOnly":true,"description":"This tagging relation ID. Used when deleting a Tagging for example."},"id":{"type":"integer","description":"Tag object unique ID"},"extra":{"description":"Tagging extra payload"}},"required":["id","name","tagging_id","web_inbox_color"]}}},"paths":{"/api/v1/messages/{id}/":{"get":{"operationId":"retrieveMessage","description":"Get a single Message by its Inbox message ID.","parameters":[{"in":"path","name":"id","schema":{"type":"string"},"description":"A unique value identifying this message.","required":true}],"tags":["Messages"],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetrieveMessage"}}},"description":""}}}}}}
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.360dialog.com/docs/inbox/inbox-api/api-ref/messages.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
