Getting startedMessaging

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") is provided to enable lodging partners to receive real-time notifications for messages sent during and after a traveler’s stay. To receive notifications, you must implement the notifications capability and then the lodging partner must subscribe to notifications. Then, after a reservation is made, a new message thread is created and two notifications are sent to the callback URL: MessageThreadCreated and MessageReceived. 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.

Finally, the attachment service is provided, which is a separate REST API that partners can use to upload message attachments and that enables travelers to download 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.

Implementing the messaging and notification capabilities 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.

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.

  • Upload and download message attachments, which relies on the attachment service.

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:

  1. 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 the MessageReceived 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.
  1. 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 
    ...
    
  2. 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 
      }  
    }
    
  3. MessageReceived webhook notification is sent.

Implementation details

  • Messages are retained for up to one year from the message thread creation date.

  • 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.

  • 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.

  • When retrieving message threads, they are returned in ascending order (from oldest to newest) based on the creation date.

  • Message attachments are handled through a separate REST API. Accepted file types include PDF, JPEG, PNG, and GIF, 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, and the partner can query for that message. A field is provided on the message for the attachment ID, which the partner can provide in the query to download the attachment.

  • 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.

  • Messaging does not currently support reservation cancellation or modification requests.

  • Messages for reservations with stay dates completed prior to Oct 23, 2023, are not supported unless a new message is added to the conversation after October 23, 2023.

  • Messaging does not currently support reservation cancellation or modification requests.

  • Cancel waiver messages (messages that are sent when Expedia requests that a lodging partner waives their cancellation policy and allows a traveler to cancel a reservation when the reservation is no longer eligible) are not supported at this time.

  • 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.

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.
  • 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.

1query {
2 property(id: "15239779", idSource: EXPEDIA) {
3 id
4 messageThreads(
5 limit: 2
6 filters: {
7 createdDate: {
8 from: "2023-09-08T15:41:38.439Z"
9 to: "2023-09-08T15:41:38.439Z"
10 operator: INCLUSIVE
11 }
12 }
13 ) {
14 totalCount
15 cursor
16 elements {
17 id
18 property {
19 id
20 }
21 primaryTraveler {
22 firstName
23 lastName
24 },
25 reservationSummary {
26 id
27 adultCount
28 childCount
29 petCount
30 alternativeIds {
31 supplierId
32 }
33 }
34 creationDateTimeUtc
35 messages(limit: 2) {
36 totalCount
37 elements {
38 id
39 body {
40 value
41 }
42 }
43 }
44 }
45 }
46 }
47}

Retrieving a message thread by ID

The messageThread query enables partners to retrieve a message thread by ID.

1query {
2 messageThread(id: "message_thread_15239779_01") {
3 id
4 property {
5 id
6 }
7 reservationSummary {
8 id
9 checkOutDate
10 checkInDate
11 adultCount
12 childCount
13 petCount
14 alternativeIds {
15 supplierId
16 }
17 }
18 primaryTraveler {
19 firstName
20 lastName
21 }
22 creationDateTimeUtc
23 messages {
24 totalCount
25 cursor
26 elements {
27 id
28 messageThread {
29 id
30 creationDateTimeUtc
31 messages {
32 totalCount
33 }
34 }
35 body {
36 value
37 }
38 creationDateTimeUtc
39 attachments {
40 id
41 name
42 }
43 fromRole
44 }
45 }
46 }
47}

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:

1query {
2 property (id: "15239779", idSource: EXPEDIA) {
3 id
4 reservations(filter: {
5 checkOutDate: {
6 from: "2024-02-05", to: "2024-03-05"
7 }
8 },
9 pageSize: 25) {
10 totalCount
11 edges {
12 node {
13 reservationIds {
14 id
15 idSource
16 }
17 messageThreadId
18 status
19 }
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.

1query {
2 property(id: "15239779", idSource: EXPEDIA) {
3 id
4 messages(
5 limit: 10
6 filters: {
7 createdDate: {
8 from: "2023-12-22T00:00:00.000Z"
9 to: "2024-01-20T20:15:52.000Z"
10 operator: INCLUSIVE
11 }
12 }
13 ) {
14 totalCount
15 cursor
16 elements {
17 id
18 messageThread {
19 id
20 }
21 body {
22 value
23 }
24 fromRole
25 creationDateTimeUtc
26 attachments {
27 id
28 name
29 uploadDateTimeUtc
30 url
31 }
32 }
33 }
34 }
35}

Retrieving a message by ID

The message query enables partners to retrieve a message using its ID.

1query {
2 message(id: "message-1664225240575") {
3 id
4 messageThread {
5 id
6 property {
7 id
8 }
9 reservationSummary {
10 id
11 checkOutDate
12 checkInDate
13 }
14 primaryTraveler {
15 firstName
16 lastName
17 }
18 }
19 body {
20 value
21 }
22 creationDateTimeUtc
23 attachments {
24 id
25 name
26 uploadDateTimeUtc
27 }
28 fromRole
29 }
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.

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.

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 messageId
15 clientMutationId
16 }
17}