Skip to content
Last updated

Manage attachments

Use the Messaging API to upload, send and retrieve image attachments in existing conversations between guests and properties.


⏱️ Estimated time to complete: 20-30 minutes

This guide explains how to:

  • Upload an image and retrieve its attachment ID.
  • Include uploaded images when sending messages.
  • Retrieve attachment metadata.
  • Download and decode image attachments.

About attachments

The Messaging API supports image attachments in existing conversations.

Common scenarios include:

ParticipantExamples
Guest
  • Reporting an issue (e.g. broken furniture, unclean room)
  • Uploading documentation (e.g. medical certificate)
  • Sharing a photo of luggage or arrival location
Property
  • Providing property access instructions (e.g. locating the entrance)
  • Sharing lockbox or smart lock photos.
  • Sending images of amenities or welcome instructions.

Attachments are associated with an existing conversation, identified by its conversation ID and accommodation ID.

You can obtain these identifiers using /messages/latest or /messages/conversations.

Existing conversations

The Messaging API supports attachments in existing conversations only.

You cannot create a new conversation using the attachment endpoints.

Available endpoints

Use the following endpoints to manage attachments:

EndpointDescription
/messages/attachments/uploadUpload a base64-encoded image and retrieve its attachment ID.
/messages/attachments/metadataRetrieve attachment information, including file name, MIME type and size.
/messages/attachments/downloadRetrieve the base64-encoded content of an attachment.
/messages/sendSend a message containing one or more previously uploaded attachment IDs.

Before you start

Make sure you have:

  • Valid Demand API credentials.
  • Your affiliate identifier (X-Affiliate-Id).
  • Access to the Messaging API.
  • An existing conversation ID and its associated accommodation ID.
  • An image that meets the supported file requirements.

All Messaging API requests require Bearer authentication and the X-Affiliate-Id header.

See Authentication for details.

File requirements and limitations

Before uploading an attachment, validate the following requirements:

RequirementDescription
Supported file typesPNG and JPEG images, including .png, .jpg and .jpeg files.
MIME typeUse the appropriate MIME type, such as image/png or image/jpeg.
Maximum file size1,048,576 bytes (1 MiB).
File encodingBase64-encoded file content.
File size calculationThe file_size value must represent the original binary file size in bytes, before base64 encoding.
Conversation contextProvide the accommodation ID and conversation ID associated with the attachment.
File size and encoding

The 1 MiB limit applies to the original binary file, not the length of its base64-encoded representation.

Base64 encoding increases the size of the transmitted data. Always calculate file_size from the original file before encoding it.


Upload an attachment

→ Use /messages/attachments/upload to upload an image to an existing conversation.

The endpoint accepts the image as a base64-encoded string and returns an attachment ID.

Step 1 – Prepare the image

Before uploading:

  1. Verify that the file is a supported PNG or JPEG image.
  2. Check that its original size does not exceed 1,048,576 bytes.
  3. Encode the file content in base64.
  4. Record the original file name, MIME type and binary file size.

Encode an image in base64

You can encode the image locally using your preferred programming language or command-line tool.

For example, using Python:

import base64
from pathlib import Path

file_path = Path("example_image.png")

file_bytes = file_path.read_bytes()

file_size = len(file_bytes)

file_content = base64.b64encode(file_bytes).decode("ascii")

print("File size:", file_size)
print("Base64 content:", file_content)

Use the resulting values in the upload request:

  • file_size: Original file size in bytes.
  • file_content: Base64-encoded image content.

Encode attachments locally or within your application. Avoid using third-party encoding services for images containing guest information or other sensitive content.

Step 2 – Upload the image

Send a POST request to /messages/attachments/upload.

Request

POST messages/attachments/upload

The request requires the following fields:

FieldDescription
accommodationUnique identifier of the property associated with the conversation.
conversationUnique identifier of the existing conversation.
file_nameOriginal file name, including its extension.
file_typeMIME type of the image.
file_sizeOriginal binary file size in bytes.
file_contentBase64-encoded content of the image.

Example request

{
  "accommodation": "6819547",
  "conversation": "cc872746-77f2-5886-ba7c-17e0497241b5",
  "file_name": "example_image.png",
  "file_type": "image/png",
  "file_size": 35,
  "file_content": "iVBORw0KGgoAAAANSUhEUgAAADAAAABAgMAAADW0NTUAAAA"
}

The file_content value above is an illustrative, shortened base64 string. In a real request, provide the complete encoded image and its actual binary size.

Example response

{
  "request_id": "25539c17-59e6-4465-ad85-d0a517a474c5",
  "data": {
    "attachment": "c82a5350-19fe-11f0-959e-1373654fdef5"
  }
}

A successful request returns HTTP 200 OK.

The data.attachment field contains the unique identifier of the uploaded attachment.

Save this ID. You'll need it to send the attachment, retrieve its metadata or download it.

Attachment uploaded

The image has been uploaded successfully.

To make it part of a message, include its attachment ID in a subsequent /messages/send request.


Send a message with attachments

Uploading an image does not automatically send it to the guest or property.

→ Use /messages/send to send a message containing the uploaded attachment.

Request

POST /messages/send

Include the attachment ID in the attachments array.

{
  "accommodation": "6819547",
  "conversation": "cc872746-77f2-5886-ba7c-17e0497241b5",
  "content": "Please see the attached image.",
  "attachments": [
    "c82a5350-19fe-11f0-959e-1373654fdef5"
  ]
}

Example response

{
  "request_id": "cdb0b154-2eae-481b-8fee-fb2725296e1f",
  "data": {
    "message": "3164e570-19e0-11f0-baca-e5019c8df435"
  }
}

The response returns the ID of the newly sent message.

Send multiple attachments

To include multiple images in one message:

  1. Upload each image separately using /messages/attachments/upload.
  2. Collect the attachment IDs returned by the API.
  3. Include those IDs in the attachments array of the /messages/send request.

For example:

{
  "accommodation": "6819547",
  "conversation": "cc872746-77f2-5886-ba7c-17e0497241b5",
  "content": "Here are the images you requested.",
  "attachments": [
    "c82a5350-19fe-11f0-959e-1373654fdef5",
    "695b7f90-2c08-11f0-9cee-134ca9b067d1"
  ]
}

For more information about sending messages, see Manage messages.


Retrieve attachment metadata

→ Use /messages/attachments/metadata to retrieve information about an existing attachment.

The endpoint returns the file name, MIME type and size.

Request

POST /messages/attachments/metadata

Provide the accommodation, conversation and attachment identifiers.

{
  "accommodation": "6819547",
  "conversation": "cc872746-77f2-5886-ba7c-17e0497241b5",
  "attachment": "c82a5350-19fe-11f0-959e-1373654fdef5"
}

Example response

{
  "request_id": "4cf641d4-dc42-4970-a1e6-8f7fb6c8785f",
  "data": {
    "metadata": {
      "file_size": 95299,
      "file_name": "example_image.png",
      "file_type": "image/png"
    }
  }
}

The response contains:

FieldDescription
data.metadata.file_sizeSize of the attachment in bytes.
data.metadata.file_nameOriginal file name.
data.metadata.file_typeMIME type of the attachment.

The metadata response contains basic file information only. It does not include the attachment's binary content.

Use /messages/attachments/download to retrieve the file content.


Download an attachment

→ Use /messages/attachments/download to retrieve the content of an attachment associated with an existing conversation.

The API returns the file content as a base64-encoded string.

Step 1 – Retrieve the attachment

Request

POST /messages/attachments/download

{
  "accommodation": "6819547",
  "conversation": "cc872746-77f2-5886-ba7c-17e0497241b5",
  "attachment": "c82a5350-19fe-11f0-959e-1373654fdef5"
}

Example response

{
  "request_id": "773e2c0d-1ab3-449b-b88a-3d6b5ce09ae7",
  "data": {
    "conversation": "cc872746-77f2-5886-ba7c-17e0497241b5",
    "file_content": "/9j/4AAQSkZJRgABAQACWAJYAAD/2wCEAAgGBgc...",
    "attachment": "c82a5350-19fe-11f0-959e-1373654fdef5"
  }
}

The response contains:

FieldDescription
data.conversationIdentifier of the conversation associated with the attachment.
data.attachmentUnique identifier of the downloaded attachment.
data.file_contentBase64-encoded content of the attachment.

The file_content value in this example is shortened for readability.

Step 2 – Decode the attachment

Decode the base64 string to restore the original image.

For example, using Python:

import base64
from pathlib import Path

encoded_content = response["data"]["file_content"]

file_bytes = base64.b64decode(encoded_content)

Path("downloaded_image.jpg").write_bytes(file_bytes)

In this example, response represents the parsed JSON response returned by /messages/attachments/download.

Use the file name and MIME type returned by /messages/attachments/metadata to determine the appropriate file extension and how to handle the downloaded content.

File handling

Treat downloaded attachments as untrusted content.

Validate the file type and apply your application's security checks before storing, displaying or processing the file.


Troubleshooting

If an attachment request fails, validate the request fields and file requirements before retrying.

IssuePossible causeRecommended action
File exceeds the maximum sizeThe original image is larger than 1,048,576 bytes.Resize or compress the image before encoding and uploading it.
File size mismatchfile_size does not match the decoded binary content.Calculate the original file size before base64 encoding and use that value in the request.
Unsupported file typeThe file is not a supported PNG or JPEG image.Convert the file to a supported format and use the appropriate MIME type.
Invalid base64 contentThe encoded string is incomplete or incorrectly formatted.Re-encode the original image and submit the complete base64 string.
Attachment cannot be retrievedThe attachment, conversation or accommodation identifier is incorrect.Verify that all identifiers refer to the same conversation and attachment.
Authentication failureThe request uses invalid credentials or an incorrect affiliate identifier.Verify the Bearer token, X-Affiliate-Id and API access.
Rate limit exceededToo many requests have been submitted.Follow the applicable rate-limit guidance and retry according to the API response.

For general error-handling guidance, see HTTP 4xx scenarios.

Example – File size mismatch

The following request declares a file size of 350 bytes, but the supplied base64 content does not represent a file of that size.

{
  "accommodation": "6819547",
  "conversation": "cc872746-77f2-5886-ba7c-17e0497241b5",
  "file_content": "iVBORw0KGgoAAAANSUhEUgAAADAAAABAgMAAADW0NTUAAAA",
  "file_name": "example_image.png",
  "file_type": "image/png",
  "file_size": 350
}

If the API validates the declared file size against the decoded content, the mismatch can cause the request to fail.

To resolve the issue:

  1. Check that the base64 content is complete.
  2. Decode the content or inspect the original binary file to determine its actual size.
  3. Update file_size to match the original binary size.
  4. Retry the upload with valid file content and metadata.

Do not use the length of the base64 string as the value of file_size. The field must contain the size of the original binary file in bytes.


Best practices

Follow these recommendations when managing attachments:

✅ Validate before uploading: Check the image format, MIME type and original file size before encoding.

✅ Use the correct conversation context: Include the accommodation and conversation identifiers associated with the attachment.

✅ Store attachment IDs: Retain the identifiers needed to send messages and retrieve attachments.

✅ Handle base64 securely: Avoid logging or exposing encoded file content, as it contains the complete attachment data.

✅ Process downloaded files safely: Validate downloaded content before storing or displaying it.

✅ Follow data-protection requirements: Apply appropriate access controls and retention policies to stored attachments.

✅ Handle errors appropriately: Validate requests before retrying and follow the applicable API rate limits.


What's next