API reference

Messaging API - API reference

Operations

All paths are relative to the Base URL in Conventions. Include the existing Supply Connectivity authentication required for your integration. JSON responses follow the success or error envelope unless the endpoint returns 204 or download bytes. Responses use Cache-Control: no-store.

Required response fields are non-null unless explicitly stated as nullable.

OperationMethod and pathSuccess
List conversationsGET /properties/{property_id}/conversations200, data.conversations
Get reservation conversationGET /properties/{property_id}/conversations/type/reservation?conversation_reference=200, data.conversation
Get conversation detailGET /properties/{property_id}/conversations/{conversation_id}200
Send text messagePOST /properties/{property_id}/conversations/{conversation_id}202
Mark conversation readPUT /properties/{property_id}/conversations/{conversation_id}/read204, no body
Upload attachmentPOST /properties/{property_id}/conversations/{conversation_id}/attachments200, data.attachment_id
Download attachmentGET /properties/{property_id}/conversations/{conversation_id}/attachments/{attachment_id}200, file bytes
Get attachment metadataGET /properties/{property_id}/conversations/{conversation_id}/attachments/{attachment_id}/file_info200

List property conversations

Returns eligible reservation conversations for one entitled property. Each conversation row includes its latest eligible message when one exists, or "messages": [] when the conversation is empty. Empty conversations may appear in the list.

Pagination uses page_id only. Clients must not send a limit, page_size, offset, or cursor parameter. Each page contains at most 50 conversations; Agoda may return fewer. Keep requesting the next page until next_page_id is null. A page with fewer than 50 items is not necessarily the last page.

GET /properties/{property_id}/conversations
GET /properties/{property_id}/conversations?page_id={page_id}
NameInTypeRequiredDescription
property_idPathstringYesAuthorized Agoda property ID. See Identifiers.
page_idQuerystringNoOpaque token from data.next_page_id. Omit for the first page. Do not send limit, page_size, offset, or cursor.
Supply Connectivity credentialsHeaderstringYesUse the existing authentication method for your integration.

Request body: none.

Success: 200 OK

{
  "data": {
    "ok": true,
    "conversations": [
      {
        "conversation_id": "418092345",
        "conversation_reference": "9384756102",
        "conversation_type": "reservation",
        "access": "read_write",
        "participants": [
          { "type": "property", "unread_messages_count": 1 },
          { "type": "guest", "unread_messages_count": 0 },
          { "type": "agoda", "unread_messages_count": 0 }
        ],
        "messages": [
          {
            "message_id": "918273644",
            "message_type": "free_text",
            "content": "Can we check in early?",
            "timestamp": "2026-07-23T07:15:30.123Z",
            "sender_type": "guest",
            "attributes": {},
            "attachment_ids": []
          }
        ]
      },
      {
        "conversation_id": "418092346",
        "conversation_reference": "9384756103",
        "conversation_type": "reservation",
        "access": "read_only",
        "participants": [
          { "type": "property", "unread_messages_count": 0 },
          { "type": "guest", "unread_messages_count": 0 }
        ],
        "messages": []
      }
    ],
    "next_page_id": null
  },
  "errors": [],
  "warnings": [],
  "meta": {
    "ruid": "dd28b426-70c2-4b16-8f16-0edddac1ac2f"
  }
}

The first row is a three-party reservation thread. The guest-origin message has not been seen by the property: the property participant has unread_messages_count: 1, the guest has 0, and agoda has 0.

FieldTypeRequiredMeaning
data.okbooleanYesJSON boolean true.
data.conversationsarrayYesConversation rows for this page. Always an array, never null. An empty page is [].
data.next_page_idstring or nullYesAlways present. Opaque token for the next page, or null on the last page.

The list response does not return property-level unread aggregates such as unread_conversations or unread_messages. Unread state appears only per conversation via each participant's unread_messages_count.

A 200 list page is complete for that page. A short page with a non-null next_page_id is complete. Continue until next_page_id is null. Incomplete property coverage, an unvalidated unread count, or a missing required binding is 503 DEPENDENCY_UNAVAILABLE without a partial page. Treat absence of a conversation on a successful page as absence, not as a dropped indeterminate row.

List 404 is not a missing conversation_id (the request has none). After the Channel Manager is entitled to property_id (403 is the not-entitled case), 404 means a required resource in that property scope is unknown, hidden, foreign, or wrong-scope. Treat it as opaque.

Relevant errors: 400 INVALID_REQUEST, 400 INVALID_PAGE_ID, 401 AUTHENTICATION_REQUIRED, 403 PROPERTY_ACCESS_DENIED, 404 RESOURCE_NOT_FOUND, 503 DEPENDENCY_UNAVAILABLE, and 500 INTERNAL_ERROR.

Get reservation conversation

Reads the reservation conversation for an Agoda booking ID.

Not every reservation at a property you are entitled to has a messaging conversation available, and a request for one that does not returns 404 RESOURCE_NOT_FOUND.

When messages are present, the response returns the newest at most 50 eligible messages (descending message_id). data.next_page_id is present and always null. Passing page_id to this endpoint returns 400 INVALID_PAGE_ID. To read messages older than the returned page, use the conversation_id from this response with Get conversation detail. The conversation is wrapped as data.conversation.

GET /properties/{property_id}/conversations/type/reservation?conversation_reference={conversation_reference}
NameInTypeRequiredDescription
property_idPathstringYesAuthorized Agoda property ID. See Identifiers.
conversation_referenceQuerystringYesAgoda booking ID matching ^[1-9][0-9]{0,14}$.
Supply Connectivity credentialsHeaderstringYesUse the existing authentication method for your integration.

Request body: none. Do not send page_id. If page_id is present, the response is 400 INVALID_PAGE_ID.

Success: 200 OK

{
  "data": {
    "ok": true,
    "conversation": {
      "conversation_id": "418092345",
      "conversation_reference": "9384756102",
      "conversation_type": "reservation",
      "access": "read_write",
      "participants": [
        { "type": "property", "unread_messages_count": 0 },
        { "type": "guest", "unread_messages_count": 0 }
      ],
      "messages": []
    },
    "next_page_id": null
  },
  "errors": [],
  "warnings": [],
  "meta": {
    "ruid": "dd28b426-70c2-4b16-8f16-0edddac1ac2f"
  }
}
FieldTypeRequiredMeaning
data.okbooleanYesJSON boolean true.
data.conversationobjectYesThe reservation conversation. Always present on 200, never null.
data.next_page_idstring or nullYesAlways present. Always null on this endpoint.

Relevant errors: 400 INVALID_REQUEST, 400 INVALID_PAGE_ID, 401 AUTHENTICATION_REQUIRED, 403 PROPERTY_ACCESS_DENIED, 404 RESOURCE_NOT_FOUND, 409 RESERVATION_CONVERSATION_CONFLICT, 503 DEPENDENCY_UNAVAILABLE, and 500 INTERNAL_ERROR.

409 RESERVATION_CONVERSATION_CONFLICT means multiple or incompatible reservation conversations prevent safe selection or creation. Do not repeat the reservation GET blindly. Contact support with meta.ruid.

Get conversation detail

Returns a supported reservation conversation and a page of eligible messages for one entitled property. The conversation is wrapped as data.conversation.

GET /properties/{property_id}/conversations/{conversation_id}
GET /properties/{property_id}/conversations/{conversation_id}?page_id={page_id}
NameInTypeRequiredDescription
property_idPathstringYesAuthorized Agoda property ID. See Identifiers.
conversation_idPathstringYesOpaque positive signed-64 decimal string.
page_idQuerystringNoOpaque token from data.next_page_id. Omit for the first page.
Supply Connectivity credentialsHeaderstringYesUse the existing authentication method for your integration.

Request body: none.

Success: 200 OK

{
  "data": {
    "ok": true,
    "conversation": {
      "conversation_id": "418092345",
      "conversation_reference": "9384756102",
      "conversation_type": "reservation",
      "access": "read_write",
      "participants": [
        { "type": "property", "unread_messages_count": 1 },
        { "type": "guest", "unread_messages_count": 0 },
        { "type": "agoda", "unread_messages_count": 0 }
      ],
      "messages": [
        {
          "message_id": "918273644",
          "message_type": "free_text",
          "content": "Can we check in early?",
          "timestamp": "2026-07-23T07:15:30.123Z",
          "sender_type": "guest",
          "attributes": {},
          "attachment_ids": []
        }
      ]
    },
    "next_page_id": "eyJvIjoibSIsInAiOiI5MTgyNzM2NDQifQ"
  },
  "errors": [],
  "warnings": [],
  "meta": {
    "ruid": "dd28b426-70c2-4b16-8f16-0edddac1ac2f"
  }
}
FieldTypeRequiredMeaning
data.okbooleanYesJSON boolean true.
data.conversationobjectYesThe conversation. Always present on 200, never null.
data.next_page_idstring or nullYesAlways present. Opaque token for older messages, or null on the last page.

Relevant errors: 400 INVALID_REQUEST, 400 INVALID_PAGE_ID, 401 AUTHENTICATION_REQUIRED, 403 PROPERTY_ACCESS_DENIED, 404 RESOURCE_NOT_FOUND, 503 DEPENDENCY_UNAVAILABLE, and 500 INTERNAL_ERROR.

Each page contains at most 50 eligible messages in descending message_id order (most recent first). A page may contain fewer, including "messages": []. next_page_id may still be a string. Continue until next_page_id is null. The next page continues with older messages. message_id, not timestamp, is the paging and ordering authority. A missing or incomplete dependency result is 503. An empty eligible window is not a missing dependency.

A message accepted with 202 may be absent from this GET until processing completes. See Eventual consistency.

Send text message

Submits a free-text message to a writable reservation conversation. A successful 202 means Agoda accepted the message at the API acceptance boundary. It does not mean the message was delivered, became externally visible on a subsequent GET, or was read.

The send is asynchronous. See Eventual consistency.

Treat access as the send and upload eligibility signal. Recheck it on every send POST. A previous read_write does not guarantee that a later write will be accepted. If access is read_only, send returns 403 CONVERSATION_READ_ONLY.

POST /properties/{property_id}/conversations/{conversation_id}
NameInTypeRequiredDescription
property_idPathstringYesAuthorized Agoda property ID. See Identifiers.
conversation_idPathstringYesOpaque positive signed-64 decimal string.
Content-TypeHeaderstringYesapplication/json; charset=utf-8.
Supply Connectivity credentialsHeaderstringYesUse the existing authentication method for your integration.

Request body:

{
  "message": {
    "content": "We can accommodate an early check-in from 14:00.",
    "attachment_ids": ["918273800"]
  }
}
FieldTypeRequiredMeaning
messageobjectYesSend payload wrapper. Unknown fields on this object are rejected.
message.contentstringYesNon-empty, well-formed text. Must satisfy Message size. Agoda does not normalize or truncate it.
message.attachment_idsarray of stringNoOpaque attachment IDs from a prior upload on this conversation. Omit or send [].

Unknown fields on the request object or on message are rejected with 400 INVALID_REQUEST. Do not send a flat { "content": "..." } body.

Content that is not well-formed UTF-16 is rejected with 400 INVALID_REQUEST. Content that fails the size dual rule is rejected with 413 MESSAGE_TOO_LARGE. An unknown attachment id is 404 RESOURCE_NOT_FOUND.

Do not send Idempotency-Key, a client message ID, a request fingerprint, or a replay key. Every POST is a new send attempt.

Success: 202 Accepted

{
  "data": {
    "ok": true,
    "message_id": "918273700",
    "guest_has_account": true,
    "attachment_ids": ["918273800"]
  },
  "errors": [],
  "warnings": [],
  "meta": {
    "ruid": "dd28b426-70c2-4b16-8f16-0edddac1ac2f"
  }
}
FieldTypeRequiredMeaning
data.okbooleanYesJSON boolean true.
data.message_idstringYesOpaque ID of the accepted message.
data.guest_has_accountbooleanYestrue when the guest has an Agoda account. false when they do not, in which case the message reaches the guest by email.
data.attachment_idsarray of stringYesAttachment IDs accepted with this send. Always present. Empty array when none.

The send 202 body has no data.status and no next_page_id.

guest_has_account appears only in this 202 success body (not on list, get, or mark-read responses).

Relevant errors: 400 INVALID_REQUEST, 401 AUTHENTICATION_REQUIRED, 403 PROPERTY_ACCESS_DENIED, 403 CONVERSATION_READ_ONLY, 404 RESOURCE_NOT_FOUND, 413 MESSAGE_TOO_LARGE, 503 DEPENDENCY_UNAVAILABLE, and 500 INTERNAL_ERROR.

On timeout, connection loss, or 500/503 after the request may have been accepted, treat the result as unknown and do not blindly resend. See Send attempts and Best practices.

Do not treat an immediate GET as a delivery check. See Eventual consistency.

Mark conversation read

Sets the property's unread counter for that conversation to zero. The operation is repeatable. The request has no body.

PUT /properties/{property_id}/conversations/{conversation_id}/read
NameInTypeRequiredDescription
property_idPathstringYesAuthorized Agoda property ID. See Identifiers.
conversation_idPathstringYesOpaque positive signed-64 decimal string.
Supply Connectivity credentialsHeaderstringYesUse the existing authentication method for your integration.

Request body: none.

Success: 204 No Content. The response has no body. This is the single exception to the JSON envelope. Use the X-Request-Id response header for support correlation.

Relevant errors: 400 INVALID_REQUEST, 401 AUTHENTICATION_REQUIRED, 403 PROPERTY_ACCESS_DENIED, 404 RESOURCE_NOT_FOUND, 503 DEPENDENCY_UNAVAILABLE, and 500 INTERNAL_ERROR. Error responses use the JSON error envelope (data: null, errors, warnings, meta).

Observable effect. The entire observable effect is that the property's unread counter for that conversation becomes zero.

Upload attachment

Uploads a file for a later send on the same conversation. Send the file as multipart/form-data. The file part is named attachment. Put the filename in Content-Disposition filename. Allowed types: JPEG (image/jpeg) and PNG (image/png) only. Maximum size: 10 MiB. Images that contain a QR code are rejected (400 INVALID_REQUEST).

POST /properties/{property_id}/conversations/{conversation_id}/attachments
NameInTypeRequiredDescription
property_idPathstringYesAuthorized Agoda property ID. See Identifiers.
conversation_idPathstringYesOpaque positive signed-64 decimal string.
attachmentBody (multipart)fileYesFile part name. Filename is Content-Disposition filename. Allowed types: JPEG (image/jpeg) and PNG (image/png) only. Maximum 10 MiB.
Content-TypeHeaderstringYesmultipart/form-data.
Supply Connectivity credentialsHeaderstringYesUse the existing authentication method for your integration.

Unsupported media type or a missing file is 400 INVALID_REQUEST. A file larger than 10 MiB is 413 MESSAGE_TOO_LARGE.

Treat access as the send and upload eligibility signal. Recheck it on every upload POST. A previous read_write does not guarantee that a later write will be accepted. If access is read_only, upload returns 403 CONVERSATION_READ_ONLY. Do not upload; continue reading if needed.

Success: 200 OK

{
  "data": {
    "ok": true,
    "attachment_id": "918273800"
  },
  "errors": [],
  "warnings": [],
  "meta": {
    "ruid": "dd28b426-70c2-4b16-8f16-0edddac1ac2f"
  }
}
FieldTypeRequiredMeaning
data.okbooleanYesJSON boolean true.
data.attachment_idstringYesOpaque ID to pass in send attachment_ids.

Relevant errors: 400 INVALID_REQUEST, 401 AUTHENTICATION_REQUIRED, 403 PROPERTY_ACCESS_DENIED, 403 CONVERSATION_READ_ONLY, 404 RESOURCE_NOT_FOUND, 413 MESSAGE_TOO_LARGE, 503 DEPENDENCY_UNAVAILABLE, and 500 INTERNAL_ERROR.

Download attachment

Returns the file as raw bytes. This success is not JSON.

GET /properties/{property_id}/conversations/{conversation_id}/attachments/{attachment_id}
NameInTypeRequiredDescription
property_idPathstringYesAuthorized Agoda property ID. See Identifiers.
conversation_idPathstringYesOpaque positive signed-64 decimal string.
attachment_idPathstringYesOpaque attachment ID from upload or a message attachment_ids entry.
Supply Connectivity credentialsHeaderstringYesUse the existing authentication method for your integration.

Success: 200 OK with the file bytes.

HeaderMeaning
Content-TypeThe file's media type.
Content-Dispositionattachment; filename= plus the file name.
X-Content-Type-Optionsnosniff.
X-Request-IdCorrelation id. Present on every response.

After upload, call Get attachment metadata until it returns 200, then download. 404 means the file is still being processed, or it has expired or been deleted. Files are kept for 28 days. Send may use attachment_id from a 200 upload.

Relevant errors: 400 INVALID_REQUEST, 401 AUTHENTICATION_REQUIRED, 403 PROPERTY_ACCESS_DENIED, 404 RESOURCE_NOT_FOUND, 503 DEPENDENCY_UNAVAILABLE, and 500 INTERNAL_ERROR. Error responses use the JSON error envelope.

Get attachment metadata

Returns public file facts only. No file bytes and no download URL.

GET /properties/{property_id}/conversations/{conversation_id}/attachments/{attachment_id}/file_info
NameInTypeRequiredDescription
property_idPathstringYesAuthorized Agoda property ID. See Identifiers.
conversation_idPathstringYesOpaque positive signed-64 decimal string.
attachment_idPathstringYesOpaque attachment ID.
Supply Connectivity credentialsHeaderstringYesUse the existing authentication method for your integration.

Success: 200 OK

{
  "data": {
    "ok": true,
    "file_name": "photo.jpg",
    "file_type": "image/jpeg",
    "file_size": 102400
  },
  "errors": [],
  "warnings": [],
  "meta": {
    "ruid": "dd28b426-70c2-4b16-8f16-0edddac1ac2f"
  }
}
FieldTypeRequiredMeaning
data.okbooleanYesJSON boolean true.
data.file_namestringYesFile name supplied at upload.
data.file_typestringYesMedia type (image/jpeg or image/png).
data.file_sizeintegerYesSize in bytes.

After upload, call Get attachment metadata until it returns 200, then download. 404 means the file is still being processed, or it has expired or been deleted. Files are kept for 28 days.

Relevant errors: 400 INVALID_REQUEST, 401 AUTHENTICATION_REQUIRED, 403 PROPERTY_ACCESS_DENIED, 404 RESOURCE_NOT_FOUND, 503 DEPENDENCY_UNAVAILABLE, and 500 INTERNAL_ERROR.

Eventual consistency

A message accepted with 202 may not appear in GET until Agoda has finished processing it. Partners MUST NOT treat an immediate GET as a delivery check.

Keep message_id from the 202. Confirm visibility with a later conversation-detail GET, or with a webhook followed by a confirming GET. Notification order is not guaranteed; message_id is the ordering authority.


Did this page help you?