Skip to content

πŸ’‘ AI Bot Integration

Important: This documentation describes the integration with our test environment. Before moving to production, please test your integration thoroughly in this environment. Contact api-support@likemagic.tech to get onboarded and receive your test environment credentials.

Mainflow

  • Guest contacts hotel
  • LIKE MAGIC receives incoming message through Bird
  • LIKE MAGIC matches the message to a guest identity and potential existing reservation
  • LIKE MAGIC request an automated answer from the AI partner and provides guest & reservation context
  • AI partner can ask for additional information from the LIKE MAGIC platform if needed (e.g. booked additional services)
  • AI partner provides a response to LIKE MAGIC
  • LIKE MAGIC send the response through Bird to the guest

Matching a message to a guest identity does not always succeed, and the identity of a conversation can change later. See Guest identity and conversation history before you design how you store guest state.

sequenceDiagram
    participant Bird
    participant "LIKE MAGIC"
    participant "AI partner"

    Bird->>"LIKE MAGIC": 1: Incoming guest message
    activate "LIKE MAGIC"
    "LIKE MAGIC"->>"LIKE MAGIC": 2: Find corresponding guest identity & reservation
    "LIKE MAGIC"->>"AI partner": 3: Guest message with guest identity & reservation context
    activate "AI partner"
    "AI partner"->>"AI partner": 4: Create answer

    opt Fetch additional information
        "AI partner"->>"LIKE MAGIC": 5: Additional information
        "LIKE MAGIC"-->>"AI partner": response
    end

    "AI partner"-->>"LIKE MAGIC": 6: Guest response via Webhook
    deactivate "AI partner"

    "LIKE MAGIC"->>Bird: 7: Respond to guest
    deactivate "LIKE MAGIC"

Information for AI partner

All the events from the AI partner are to be posted (POST) on a webhook provided by LIKE MAGIC.

Whatsapp Number (Test Environment)

+1 (226) 640-5907 (Test environment only - in production you will use the dedicateds number of the hotel)

URL

The webhook URLs below use your tenant-specific Base URL (see Prerequisites & Configuration) - shown as a pattern on the central docs and filled in automatically on your own environment.

Open this page on your own environment

We strongly suggest heading over to your tenant's own copy of this page now, to see your real URLs instead of the patterns below and eliminate any guessing:

https://monitoring.<your-domain>/api-doc/use-case/partner/ai-bot-integration/

Just swap in your <your-domain>.

Environment Endpoint
Test Environment /api/integration-service/webhook/unified-messaging/<tenant>/callback
Test BaseUrl
Test Tenant likemagic-test

Task API Integration

For the best possible integration experience, we recommend integrating with our Task API. This allows your AI bot to: - Create tasks based on guest requests - Track task status and progress - Handle service requests efficiently - Manage hotel operations seamlessly

For detailed Task API documentation and integration guidelines, refer to our Manage Tasks Guide.

Security

All incoming webhooks are secured with a lm-webhook-secret header. Contact api-support@likemagic.tech to get your test environment secret key.

AI Events description

Property Type Contract Description
event Enum required Defines the type of the event ai.response
conversationId UUID optional Required for type ai.response, ai.action Is shared by LM when receiving the initial guest message
messageId UUID optional Required for type ai.response Unique identifier defined by the AI partner, e.g. 42827c8e-0354-4b13-9319-5093b83886fe
type Enum required Defines in more detail the event
content Object optional Required for type ai.response Answer from the AI partner. The content of this object is dynamic and depends on the type of the message.

AI Message Response

A response from the AI to be sent to the guest.

{
    "event": "ai.response",
    "conversationId": "367fecba-bc23-418b-aef2-7943180860d4",
    "messageId": "U-1",
    "type": "text",
    "content": "Chatbot response to the conversation"
}

Sample CURL

curl -X 'POST' \
  '{{monitoringUrl}}/api/integration-service/webhook/unified-messaging/<tenant>/callback' \
  -H 'accept: */*'
  -H 'Content-Type: application/json' \
  -d '{
    "event": "ai.response",
    "conversationId": "367fecba-bc23-418b-aef2-7943180860d4",
    "messageId": "U-1",
    "type": "text",
    "content": "Chatbot response to the conversation"
}'

Human intervention needed

Informing LM that a human needs to take over the conversation

{
    "event": "ai.action",
    "conversationId": "367fecba-bc23-418b-aef2-7943180860d4",
    "type": "HUMAN_INTERVENTION_NEEDED",
}

Sample CURL

curl -X 'POST' \
  '{{monitoringUrl}}/api/integration-service/webhook/unified-messaging/<tenant>/callback' \
  -H 'accept: */*'
  -H 'Content-Type: application/json' \
  -d '{
    "event": "ai.action",
    "conversationId": "367fecba-bc23-418b-aef2-7943180860d4",
    "type": "HUMAN_INTERVENTION_NEEDED",
}'

Webhook to be provided by AI Partner

LIKE MAGIC requires the AI partner to provide an webhook endpoint so the partner can consume events from LM.

Please share the URL with your technical contact person from LM

Security

All outgoing webhooks are secured with a lm-webhook-secret header. Please contact your technical contact person from LM to get the secret.

Webhook Description

Property Type Contract Description
event Enum required Defines the type of the event lm.action
type Enum required Defines in more detail the event whatsapp
tenantName String required Name of the LIKE MAGIC customer
conversationId UUID required Required for type whatsapp | HUMAN_TAKE_OVER |AI_TAKE_OVER unique identifier for a conversation which can contain multiple messages
messageId UUID optional Required for type whatsapp unique identifier of the specific message
pmsReservationId String optional Required for type whatsapp If available the linked reservation id from the PMS will be set
pmsPropertyId String optional Required for type whatsapp If available the linked property id from the PMS will be set. If no property id can be determined the field is not sent
content Object optional Required for type whatsapp | sms | booking_dot_com Message of the guest
String required if event = lm.message
Image object required if event =lm.image
File object required if event = lm.file
Notification object required if event = lm.notification
createdAt DateTime String (ISO-8601) required DateTime String when the message was created
guestActor GuestActor object optional Guest details. Sent for lm.message, lm.image, lm.file and lm.notification. Not sent for lm.action, which is a conversation level signal

Guest Actor

Property Type Contract Description
guestIdentityId Long optional Durable identifier of the guest across conversations and channels within one tenant. Empty while the contact is not yet identified, see Guest identity and conversation history
userProfileId Long optional Identifier of the guest profile. Use it to load conversation history and profile data. Set whenever guestIdentityId is set and a profile exists
firstName String optional First name of guest if available
lastName String optional Last name of guest if available
phone String optional Phone number if available
email String optional Email of guest if available

Image

Property Type Contract Description
mediaUrl String required URL of the image, to be fetched from LM
caption String optional Optional caption provided by the guest

File

Property Type Contract Description
mediaUrl String required URL of the file, to be fetched from LM
contentType String required File contentType e.g. video/mp4
caption String optional Optional caption provided by the guest

Notification

Property Type Contract Description
text String required Text of the trigger based template message
templateName Enum required Name of the LIKE MAGIC template: COMPANION_ADDED, PRE_CHECKIN_REMINDER, RESERVATION_CREATED, CHECKIN, CHECKED_IN, CHECKIN_INTRODUCTION, CHECKIN_REMINDER, CHECKOUT_ALERT, CHECKOUT_FOLLOW_UP, CHECKOUT_INTRODUCTION, ID_CHECK_DECLINED, INVOICE, RESERVATION_CANCELED
language Enum required Language used of the template, e.g. DE or EN

Guest identity and conversation history

Four identifiers appear in these events and they serve different purposes.

Identifier Use it for Stability
guestIdentityId Grouping a guest's conversations over time Durable, but can be superseded
userProfileId Loading conversation history and profile data through our APIs Stable in normal operation. Can change when two profiles are merged
conversationId Correlating events within one conversation Not durable, can change
messageId Matching a specific message across changes Stable, preserved in all cases

When guestIdentityId is empty

We set guestIdentityId once we have matched the sender's phone number or email to a known guest. It is empty when:

  • the guest writes from a phone number or email we have never linked to a reservation
  • the contact belongs to an OTA placeholder address rather than to the guest
  • our person record matching could not resolve the contact unambiguously

While it is empty we cannot tell you which other conversations belong to the same person, and neither history endpoint helps. Use guestActor.phone if you need a best effort grouping on your side.

The value fills in on its own once a reservation carrying that contact reaches us. It is not guaranteed to ever fill in. A contact that never appears on a reservation stays unidentified.

Loading a guest's conversation history

With the userProfileId from the event:

Endpoint Returns
GET /guest-conversations/by-user-profile-id/{userProfileId} Paginated conversations of that guest, newest first
GET /guest-conversations/{conversationId}/messages Paginated messages of one conversation

If you only hold a guestIdentityId, resolve the profile first with GET /user-profiles/by-guest-identity-id/{guestIdentityId}. The id in the response is the userProfileId. A guest identity almost always has a profile, but the call can return 404, so handle that case.

Do not swap the two ids

Do not pass a guestIdentityId where a userProfileId is expected. They are separate id spaces. The call usually returns 404 and can in rare cases return a different guest's conversations.

When a conversation is re-keyed

When a contact that was not identified later becomes identified, or an operator resolves an identity conflict, we move the affected messages onto the identified guest and the conversationId changes.

Plan for the following:

  • A conversationId you hold can change. The next event for that guest carries the new one.
  • A conversation can be re-keyed more than once.
  • We delete a conversation once a move leaves it empty, so a GET on that conversationId returns 404. Treat that as superseded rather than invalid and resolve the guest again.
  • guestIdentityId can also be superseded. When an operator merges several identities we create a new one, so two values you have seen can both be replaced by a third.
  • A conversation can hold messages for more than one contact address of the same guest, for example a phone number and an email. A move covers the messages of the contact that was linked, so a conversation can be split.

Because of the last point, do not assume that every message you received under the old conversationId belongs to the newly resolved guest. Match on messageId, which we preserve. Messages you saw under the old conversation reappear under the new one with the same message ids.

We do not currently push an event when a conversation is re-keyed. You can derive it from the events you already receive. If the guestIdentityId for a conversationId you know changes, or a conversation you know appears under a new id, re-read that guest's history through the endpoints above.

Guest message

Message of a guest

{
  "event": "lm.message",
  "type": "whatsapp",
  "tenantName": "LIKE MAGIC",
  "conversationId": "CONVERSATION_ID_LIKEMAGIC",
  "messageId": "MESSAGE_ID_LIKEMAGIC",
  "pmsReservationId": "PMS_RESERVATION_ID",
  "pmsPropertyId": "PMS_PROPERTY_ID",
  "content": "An incomming message from a guest",
  "createdAt": "2025-01-14T15:55:59.547Z",
  "guestActor": {
      "guestIdentityId": 12345,
      "userProfileId": 67890,
      "firstName": "John",
      "lastName": "Smith",
      "email": "john.smith@example.com",
      "phone": "+15550100000"
  }
}

Sample CURL

curl -X 'POST' \
  'https://AI_PARTNER_URL/webhook' \
  -H 'accept: */*'
  -H 'Content-Type: application/json' \
  -d '{
    "event": "lm.message",
    "type": "whatsapp",
    "tenantName": "LIKE MAGIC"
    "conversationId": "CONVERSATION_ID_LIKEMAGIC",
    "messageId": "MESSAGE_ID_LIKEMAGIC",
    "pmsReservationId": "PMS_RESERVATION_ID",
    "pmsPropertyId": "PMS_PROPERTY_ID",
    "content": "An incomming message from a guest",
    "createdAt": "2025-01-14T15:55:59.547Z",
    "guestActor": {
      "guestIdentityId": 12345,
      "userProfileId": 67890,
      "firstName": "John",
      "lastName": "Smith",
      "email": "john.smith@example.com",
      "phone": "+15550100000"
  }
}'

Guest image

Message of a guest containing an image.

{
  "event": "lm.image",
  "type": "whatsapp",
  "tenantName": "LIKE MAGIC",
  "conversationId": "CONVERSATION_ID_LIKEMAGIC",
  "messageId": "MESSAGE_ID_LIKEMAGIC",
  "pmsReservationId": "PMS_RESERVATION_ID",
  "pmsPropertyId": "PMS_PROPERTY_ID",
  "content": {
    "mediaUrl": "https://media.likemagic.tech/VgYYE0oT",
    "caption": "Image caption"
  },
  "createdAt": "2025-01-14T15:55:59.547Z",
  "guestActor": {
      "guestIdentityId": 12345,
      "userProfileId": 67890,
      "firstName": "John",
      "lastName": "Smith",
      "email": "john.smith@example.com",
      "phone": "+15550100000"
  }
}

Guest file

Message of a guest containing a file. Check the contentType to understand the file Type

The contentType can be

  • video/mp4
  • audio/ogg
  • application/pdf and more
{
  "event": "lm.file",
  "type": "whatsapp",
  "tenantName": "LIKE MAGIC",
  "conversationId": "CONVERSATION_ID_LIKEMAGIC",
  "messageId": "MESSAGE_ID_LIKEMAGIC",
  "pmsReservationId": "PMS_RESERVATION_ID",
  "pmsPropertyId": "PMS_PROPERTY_ID",
  "content": {
    "mediaUrl": "https://media.likemagic.tech/VgYYE0oT",
    "contentType": "video/mp4",
    "caption": "File caption"
  },
  "createdAt": "2025-01-14T15:55:59.547Z",
  "guestActor": {
      "guestIdentityId": 12345,
      "userProfileId": 67890,
      "firstName": "John",
      "lastName": "Smith",
      "email": "john.smith@example.com",
      "phone": "+15550100000"
  }
}

Fetching data from LM based on mediaUrl

To fetch information based on the mediaUrl in the test environment, the AI partner must call:

GET /api/unified-messaging/guest-conversations/attachments?mediaUrl={mediaUrl}

API Reference

For complete API documentation including all endpoints, request/response schemas and interactive testing:

πŸ‘‰ Unified Messaging API - Live Docs

Trigger based LIKE MAGIC notification

If you are interest in LIKE MAGICs' trigger based configuration please consume the lm.notification events. These contain the content of the templates used with the guest.

{
  "event": "lm.notification",
  "type": "whatsapp",
  "tenantName": "LIKE MAGIC",
  "conversationId": "CONVERSATION_ID_LIKEMAGIC",
  "messageId": "MESSAGE_ID_LIKEMAGIC",
  "pmsReservationId": "PMS_RESERVATION_ID",
  "pmsPropertyId": "PMS_PROPERTY_ID",
  "content": {
    "text": "Hey JohnπŸ™Œ\nGrossartig, du bist nun Teil der LIKE MAGIC Familie!πŸŽ‰\nMit unserer Mobile-Check-in LΓΆsung hast du deinen Aufenthalt in der eigenen Hand. Keine langwierigen Prozesse mehr",
    "templateName"="CHECKIN_REMINDER", 
    "language"="DE"
  },
  "createdAt": "2025-08-19T03:36:11.344091Z",
  "guestActor": {
      "guestIdentityId": 12345,
      "userProfileId": 67890,
      "firstName": "John",
      "lastName": "Smith", 
      "email": "john.smith@example.com",
      "phone": "+15550100000"
  }
}

Sample CURL

curl -X 'POST' \
  'https://AI_PARTNER_URL/webhook' \
  -H 'accept: */*'
  -H 'Content-Type: application/json' \
  -d '{
    "event": "lm.notification",
    "type": "whatsapp",
    "tenantName": "LIKE MAGIC"
    "conversationId": "CONVERSATION_ID_LIKEMAGIC",
    "messageId": "MESSAGE_ID_LIKEMAGIC",
    "pmsReservationId": "PMS_RESERVATION_ID",
    "pmsPropertyId": "PMS_PROPERTY_ID",
    "content": {
      "text": "A template based notification",
      "templateName"="CHECKIN_REMINDER", 
      "language"="DE"
    },
    "createdAt": "2025-01-14T15:55:59.547Z",
    "guestActor": {
      "guestIdentityId": 12345,
      "userProfileId": 67890,
      "firstName": "John",
      "lastName": "Smith",
      "email": "john.smith@example.com",
      "phone": "+15550100000"
  }
}'

Human take over

LM informs the AI partner that the conversation is taken over by a human

{
  "event": "lm.action",
  "type": "HUMAN_TAKE_OVER",
  "tenantName": "LIKE MAGIC"
  "pmsPropertyId": "PMS_PROPERTY_ID",
  "conversationId": "CONVERSATION_ID_LIKEMAGIC"
}

Sample CURL

curl -X 'POST' \
  'https://AI_PARTNER_URL/webhook' \
  -H 'accept: */*'
  -H 'Content-Type: application/json' \
  -d '{
    "event": "lm.action",
    "type": "HUMAN_TAKE_OVER",
    "tenantName": "LIKE MAGIC"
    "pmsPropertyId": "PMS_PROPERTY_ID",
    "conversationId": "CONVERSATION_ID_LIKEMAGIC"
}'

AI take over

LM informs the AI partner that the conversation should be taken over by them

{
  "event": "lm.action",
  "type": "AI_TAKE_OVER",
  "tenantName": "LIKE MAGIC"
  "pmsPropertyId": "PMS_PROPERTY_ID",
  "conversationId": "CONVERSATION_ID_LIKEMAGIC"
}

Sample CURL

curl -X 'POST' \
  'https://AI_PARTNER_URL/webhook' \
  -H 'accept: */*'
  -H 'Content-Type: application/json' \
  -d '{
    "event": "lm.action",
    "type": "AI_TAKE_OVER",
    "tenantName": "LIKE MAGIC"
    "pmsPropertyId": "PMS_PROPERTY_ID",
    "conversationId": "CONVERSATION_ID_LIKEMAGIC"
}'

Interacting with a guest-conversation

We provide option to do following changes to a guest-conversation

  • resolve a conversation
  • change the associated pmsPropertyId

both endpoints return the current guest conversation object.

API Reference

For complete API documentation including all endpoints, request/response schemas and interactive testing:

πŸ‘‰ Unified Messaging API - Live Docs

Integration Certification

Before moving your integration to production, you'll need to complete a certification process with LIKE MAGIC. This ensures your integration meets our quality standards and follows best practices.

Certification Process

  1. Complete your integration development and testing in the test environment
  2. Ensure all required endpoints are implemented and working correctly
  3. Verify error handling and edge cases are properly managed
  4. Test all message types and interactions thoroughly

Schedule Certification Call

When you're ready to certify your integration: 1. Email api-support@likemagic.tech with subject "Integration Certification Request" 2. Include your test environment tenant name and a brief summary of your integration and the supported use cases 3. Provide your availability for a certification call 4. Our team will review your integration and schedule a certification meeting

During the certification call, we'll verify your integration's functionality and provide any necessary feedback before approving it for production use.