Intro to messaging
The Lodging Supply GraphQL API now provides the ability to retrieve and send messages to travelers. Messaging supports back-and-forth messages sent between the traveler and the lodging partner, and it enables connectivity providers to query for message threads (conversations) by property as well as to query for a specific message thread by ID.
In addition, a notification service (also referred to as "webhooks") enables lodging partners to receive real-time notifications for messages sent before, during, and after a traveler’s stay. To receive notifications:
- You must implement the notifications capability and then subscribe to the messaging event types.
MessageThreadCreated
,MessageReceived
, andMessageAttributesUpdated
event types are supported and you must subscribe to them all. - After a reservation is made, a new message thread is created and two notifications are sent to the callback URL:
MessageThreadCreated
andMessageReceived
. - After that, either party (traveler or partner) can send a message, which adds a message to the reservation's message thread and a
MessageReceived
notification is sent. As a message's status changes as it moves through moderation, aMessageAttributesUpdated
notification is sent.
Finally, the attachment service is provided, which is a separate REST API that partners must implement in order to upload and download message attachments.
Note: You can download the Messaging launch kit.
After you have integrated this capability, please share your feedback here. Your feedback is valuable to us and will be shared directly with the Product teams responsible for delivering new API features and functionality.
Implementation of the messaging capability, notifications capability, and attachment service is mandatory to enable messaging between travelers and partners. After integrating these capabilities, partners can
Retrieve a message thread (and its messages) by ID, which relies on the
messageThread
query, passing in the message thread’s ID that was obtained from the webhook notification.–OR–
Retrieve a message by ID, which relies on the
message
query, passing in the message ID that was included in the webhook notification.Add a message to a message thread, which relies on the
sendMessage
mutation. If the partner wants to send an attachment in the message, the partner must upload the attachment first and reference the attachment ID in the message.Upload and download message attachments, which relies on the attachment service.
In addition to this core functionality, partners can
Retrieve message threads (conversations) for a property, which relies on the
messageThreads
query, which uses the property’s EID and message thread creation date to retrieve message thread IDs and messages, including message IDs and details. This is useful if a partner needs to build conversation history for a property.Retrieve all messages for a property, which relies on the
messages
query and is useful if the messages were not previously retrieved or in the event of message loss.Retrieve a message by ID, which relies on the
message
query to retrieve a message using its ID.
If you are unfamiliar with GraphQL concepts, such as queries and mutations, read this overview to learn more.
Workflow
After the messaging capability, notifications capability, and attachment service are implemented, the following workflow is possible:
A traveler makes a reservation, which creates the message thread, and the
MessageThreadCreated
webhook notification is sent to the lodging partner. A message is also created, which captures the reservation event, and theMessageReceived
notification is also sent.Here is an example of the
MessageReceived
notification, which includes the message ID and Expedia property ID (EID):{ "notification_id": "63376d68-651a-11ed-9022-0242ac120442", "event_name": "MessageReceived", "creation_time": "2023-01-10T17:13:36.140Z", "payload": { "property_id": 15239779, "message_thread_id": "63676d68-651a-11ed-9022-0242ac120432", "message_id": "63676d68-651a-11ed-9022-0242ac12662", "from_role": "TRAVELER", "reservation_id": "63676d68-651a-11ed-9022-0242ac120882" } }
After the reservation is created, either party (traveler or partner) can add a message to the message thread.
- If the partner adds a message, they use their software, which relies on the
sendMessage
mutation and sends the message to the traveler. - If the traveler sends a message using the message feature at the point of sale, the message is added to the reservation’s message thread and a
MessageReceived
notification is sent to the partner.
Lodging partner retrieves the message using the ID using the
message
query. Here is a snippet of the query, which passes in the message ID in the notification. For a full example, see Retrieving a message.query { message(id: "63676d68-651a-11ed-9022-0242ac12662") { body { value } messageThread { id property { id } reservationSummary { id checkOutDate checkInDate ...
Lodging partner responds to the message using their software (using the
sendMessage
mutation and the message thread ID in the notification). Here is an example of the mutation:mutation { sendMessage( input: { body: "Thank you for the booking.", messageThreadId: "63676d68-651a-11ed-9022-0242ac120432" } ) { messageId clientMutationId } }
MessageReceived
webhook notification is sent.
Message types
When a message is retrieved, its type can be included in the payload, which indicates why the message was sent (type
field on the MessageThreadMessage
object). Similarly, message type is included in the MessageReceived
and MessageAttributesUpdated
webhook notifications. The following table lists the possible message types that may be sent.
Message type | Description |
---|---|
BOOKING | Traveler reserved a property. |
FREE_TEXT | Text response was sent from the traveler or lodging partner. |
FREE_TEXT_WITH_ATTACHMENT | An attachment was sent, typically without sending a message. |
REQUEST_CANCEL_WAIVER_CREATED | Creation of a cancellation waiver was requested. |
REQUEST_CANCEL_WAIVER_RESOLVED | Cancellation waiver was created (request was resolved). |
SPECIAL_REQUEST | Messages from the traveler were sent at time of booking. (All subsequent messages by either traveler or partner are captured by FREE_TEXT messages.) |
SUPPLIER_CANCEL_CONFIRMED | Lodging partner confirmed the cancellation. |
SUPPLIER_CANCELLED_BOOKING | Lodging partner canceled a reservation. |
SUPPLIER_CONFIRMED_BOOKING | Lodging partner confirmed the reservation. |
SUPPLIER_EDITED_BOOKING | Lodging partner modified a reservation. |
TRAVELER_CANCELLED_BOOKING | Traveler cancelled a reservation. |
TRAVELER_REQUESTED_BOOKING_EDIT | Traveler requested a change to a reservation. |
Implementation details
Message threads become inactive either three years after the message thread's creation date or one year after the reservation checkout date, whichever is later. Inactive message thread and their messages cannot be replied to.
When a traveler sends multiple documents in a message (through email or the traveler dashboard), the message will include an attachment ID for each document that the traveler included in the message. A URL to download each attachment is also provided.
If a reservation includes multiple rooms, a message thread is created for each room in the reservation because each room is assigned its own reservation ID.
Message attachments are handled through a separate REST API. Accepted file types include PDF, JPEG, and PNG, and each attachment can be up to 5MB. Each attachment has its own ID, and only one document can be uploaded at a time.
Notifications are not sent when attachments are uploaded. Rather, the partner will receive a notification for a message. The partner can query for that message, and the attachment ID is included in the results.
To receive notifications, your endpoint must use Transport Layer Security (TLS) 1.2 or 1.3, to provide over-the-wire encryption (HTTPS).
Be aware that the following information is redacted in messages:
- Competitor information
- Credit card information
- Bank routing numbers
- IBAN numbers
- Phone numbers
- Email addresses
- Domain names
- Email addresses
- URLs (except for these: host.virtualkey.co, o.hmwy.io, t.hmwy.io, homeaway.tumblr.com, facebook.com/homeaway, pinterest.com/homeaway, twitter.com/homeaway, plus.google.com/+homeawaycom, linkedin.com/company/homeaway, instagram.com/homeaway, youtube.com/homeawayvacation)
Limitations and considerations
Access to this capability is at the connectivity partner level; this means you query by property ID, message thread ID, or message ID, but you cannot query by lodging partner.
The messaging capability does not support the following at this time:
- Reservations made through Expedia Partner Solutions (Expedia Affiliate Network) integrations
- Reservation cancellation or modification requests
- Cancellation waiver messages (messages that are sent when a lodging partner waives their cancellation policy and allows a traveler to cancel a reservation)
- Reservations with stay dates completed prior to October 23, 2023, unless a new message is added to the conversation after October 23, 2023
If the partner sends a message to a guest using a masked email address (outside of the messaging component of EPC), the content of that message is not available in the
messageThread
query response. A message is added to the message thread that an email was sent, but the email body is not available.Throttling is not supported for notifications. When a new event occurs, all notifications are sent to the partner.
Minimum certification requirements
To complete certification for the messaging capability, you must prove that your software can perform the following:
- Retrieve a message thread (and its messages) by ID
- Retrieve message threads (conversations) for a property
- Retrieve a message by ID
- Add a message to a message thread
- Upload message attachments
- Receive real-time notifications when a reservation is made, when a traveler sends a message during or after a their stay, or when a message's status changes as it moves through moderation
Retrieving message threads for a property
Use the messagethreads
query to retrieve message threads associated with a property.
- You can retrieve message threads by property for 30-day date ranges (based on creation date), up to a year in the past.
- You can limit the number of message threads returned.
- You can limit the number of messages returned for each message thread.
- By default, message threads are returned in ascending order (from oldest to newest) based on the creation date.
In this example, up to two message threads are retrieved if they occurred on September 8, 2023, and only two messages are retrieved for each message thread.
- Request
- Response
1query {2 property(id: "15239779", idSource: EXPEDIA) {3 id4 messageThreads(5 limit: 26 filters: {7 createdDate: {8 from: "2023-09-08T15:41:38.439Z"9 to: "2023-09-08T15:41:38.439Z"10 operator: INCLUSIVE11 }12 }13 ) {14 totalCount15 cursor16 elements {17 id18 property {19 id20 }21 primaryTraveler {22 firstName23 lastName24 },25 reservationSummary {26 id27 adultCount28 childCount29 petCount30 alternativeIds {31 supplierId32 }33 }34 creationDateTimeUtc35 messages(limit: 2) {36 totalCount37 elements {38 id39 body {40 value41 }42 }43 }44 }45 }46 }47}
Retrieving a message thread by ID
The messageThread
query enables partners to retrieve a message thread by ID. By default, messages in the thread are returned in ascending order (from oldest to newest) based on the creation date, though you can specify to retrieve them in descending order.
- Request
- Response
1query {2 messageThread(id: "28fc1ba4-c984-41ce-abd3-281fa") {3 id4 property {5 id6 }7 reservationSummary {8 id9 checkOutDate10 checkInDate11 adultCount12 childCount13 petCount14 alternativeIds {15 supplierId16 }17 }18 primaryTraveler {19 firstName20 lastName21 }22 creationDateTimeUtc23 messages {24 totalCount25 cursor26 elements {27 id28 body {29 value30 }31 creationDateTimeUtc32 attachments {33 id34 name35 }36 fromRole37 }38 }39 }40}
Retrieving a reservation's message thread ID
If you have adopted the reservation retrieval capability, you can use the reservation
query to retrieve the message thread ID associated with a reservation. In particular, the messageThreadId
field has been added to the Reservation
object.
Here an example request:
- Request
- Response
1query {2 property (id: "15239779", idSource: EXPEDIA) {3 id4 reservations(filter: {5 checkOutDate: {6 from: "2024-02-05", to: "2024-03-05"7 }8 },9 pageSize: 25) {10 totalCount11 edges {12 node {13 reservationIds {14 id15 idSource16 }17 messageThreadId18 status19 }20 }21 }22 }23}
Retrieving messages for a property
The messages
query enables partners to retrieve historical messages for property if they were not previously retrieved or in event of message loss. Messages are returned in ascending order (from oldest to newest) based on the creation date.
Note that the reservation ID included in messages (reservationSummary : id
) is Expedia's internal reservation UUID, and the partner’s confirmation ID is provided by reservationSummary : alternativeIds : supplierId
field.
- Request
- Response
1query {2 property(id: "15239779", idSource: EXPEDIA) {3 id4 messages(5 limit: 106 filters: {7 createdDate: {8 from: "2023-12-22T00:00:00.000Z"9 to: "2024-01-20T20:15:52.000Z"10 operator: INCLUSIVE11 }12 }13 ) {14 totalCount15 cursor16 elements {17 id18 messageThread {19 id20 }21 body {22 value23 }24 fromRole25 creationDateTimeUtc26 attachments {27 id28 name29 uploadDateTimeUtc30 url31 }32 }33 }34 }35}
Retrieving a message by ID
The message
query enables partners to retrieve a message using its ID.
- Request
- Response
1query {2 message(id: "message-1664225240575") {3 id4 messageThread {5 id6 property {7 id8 }9 reservationSummary {10 id11 checkOutDate12 checkInDate13 }14 primaryTraveler {15 firstName16 lastName17 }18 }19 body {20 value21 }22 creationDateTimeUtc23 attachments {24 id25 name26 uploadDateTimeUtc27 }28 fromRole29 }30}
Uploading an attachment
The attachment service enables partners to upload partner attachments that can be associated with messages. This service is a separate REST API, which is documented here.
- Request
- Response
1curl --request POST \2 --url https://api.expediagroup.com/supply-lodging/v1/files?type=messageThreadId&value=cf109fe4-5641-11ee-8c99-0242ac120002 \3 --header 'Authorization: Bearer DXqM0WcAvIq2y2tskJ-bpdavLsmb42_rXE6-iudzZU8:WTAL5CBEhgZfkY3kDNEY6qD0fX2jt5mUoisWWQymjOk' \4 --header 'Content-Type: multipart/form-data' \5 --form 'content=@C:\Users\rmishra\Documents\Photos\Image3.jpg'
Adding a message to a message thread
After you implement the sendMessage
mutation, partners can add a message to a message thread using its ID. If attachments were uploaded using the attachment service, they can also be added to the message thread.
- Request
- Response
1mutation {2 sendMessage(3 input: {4 attachmentIds: [5 "b3f7beb8-5641-11ee-8c99-0242ac120002",6 "b9ee73de-5641-11ee-8c99-0242ac120002"7 ],8 body: "Thank you for the booking.",9 clientMutationId: "c81529c6-5641-11ee-8c99-0242ac120002",10 messageThreadId: "cf109fe4-5641-11ee-8c99-0242ac120002"11 }12 )13 {14 messageId15 clientMutationId16 }17}