# Manage attachments

**Use the Messaging API to manage image attachments in guest and accommodation conversations.**

Enhance post-booking communication by uploading, sending, and retrieving images securely.

div
strong
 ⏱️ Estimated time to complete:
 30-40 minutes

## About attachments

Attachments allow guests and hosts to exchange images for:

* Clarifying issues (e.g., broken furniture, unclean rooms)
* Sharing arrival details.
* Providing supporting visuals (e.g., documents or photos)


### Common scenarios

| User | Examples |
|  --- | --- |
| **Guest** | * Reporting an issue (e.g. broken furniture, unclean room)
* Uploading documentation (e.g. medical certificate)
* Sharing a photo of luggage or arrival location

 |
| **Accommodation (property)** | * Providing property access instructions (e.g. locating the entrance)
* Sharing lockbox or smart lock photos.
* Sending images of amenities or welcome instructions.

 |


### Available endpoints

Use the following endpoints to manage attachments:

| Endpoint | Use it to ... |
|  --- | --- |
| [/messages/attachments/upload](/demand/docs/open-api/demand-api/attachments/uploadattachment) | Upload an image file (up to 1MB) to a conversation. |
| [/messages/attachments/metadata](/demand/docs/open-api/demand-api/attachments/getattachmentmetadata) | Retrieve metadata for an uploaded attachment (e.g. name, size, type). |
| [/messages/attachments/download](/demand/docs/open-api/demand-api/attachments/downloadmessageattachment) | Download an attachment using its ID and conversation context. |


Authentication
All endpoints require valid partner authentication. See the [authentication guide](/demand/docs/development-guide/authentication) for details.

### File requirements and limitations

Before uploading images, keep the following constraints in mind:

| Requirement | Details | Error if violated |
|  --- | --- | --- |
| Supported file types | - Accept only image files: image/png, image/jpg, image/jpeg
- Videos, documents, and other file types are not supported.

 | 415 Unsupported Media Type |
| File size limit | - Maximum file size: **1MB**.

 | 400 Bad Request |
| Encoding | - The file must be **base64-encoded** before upload (see recommendations)
- `file_size` must reflect the original binary file size of the file in bytes, not the length of the base64 encoded string.
- Files are uploaded in an encoded format and stored securely.

 | 400 Bad Request |
| Upload context | - Upload files only to existing conversations.
- Requires conversation ID, accommodation ID, reservation ID.
- Uploaded files that are not linked to a message are retained for up to 24 hours.

 | 400/404 Bad Request |
| Multiple images | - To send multiple images in a message, first upload each image individually, then include an array of their IDs in the attachments field of a [/messages/send endpoint](/demand/docs/open-api/demand-api/messages/sendmessage) request.

 | 400 Bad Request |
| Rate limits | - A maximum of **100 requests per minute** is allowed per partner.

 | [429 Too Many Requests](/demand/docs/support/error-handling/http-4xx-scenarios#429---too-many-requests). |


## Uploading an attachment

→ Use the [/messages/attachments/upload endpoint](/demand/docs/open-api/demand-api/attachments/uploadattachment) to upload a file to a conversation.

### Required parameters

All three identifiers are required to ensure that the attachment is correctly linked to the guest and booking context:

| Parameter | Description |
|  --- | --- |
| `accommodation` | The ID of the accommodation associated with the conversation. |
| `conversation` | The ID of the target conversation. |
| `file_content` | Base64-encoded content of the image (See recommendations below) |
| `file_name` | Name of the file (e.g., example_image.png) |
| `file_type` | The MIME type of the file (e.g., image/png). |
| `file_size` | Original file size in bytes (before encoding) Note: Only files smaller than 1MB are supported. |


You can obtain the accommodation and conversation IDs by retrieving existing messages (via messsages/latest endpoint) and/or conversations (using messages/conversations).

### Example request


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

### Example response


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

Use the attachment field to later retrieve metadata or download the file.

### Base64 recommendations

Base64 encoding converts a file (such as an image) into a text format. This is useful for safely sending files in JSON requests or over systems that expect text—not binary data.

div
strong
✓ To send files via the Messaging API, you must convert your image to base64
You can either:

* Use an online tool encoder such as base64-image.
* Use your computer terminal app running:
`base64 -i your-image.jpg -o output.txt` (for Linux or macOS)
or for Windows:
`[Convert]::ToBase64String((Get-Content "C:\path\to\your-image.jpg" -Encoding Byte)) > output.txt`


Important
* Your base64-encoded image must be smaller than 1MB.
* Keep it secure - Don’t share base64 strings publicly—they contain the full file content.
* Only upload images relevant to the conversation, and always comply with data protection regulations.


## Retrieving attachment metadata

→ Use the [messages/attachments/metadata endpoint](/demand/docs/open-api/demand-api/attachments/getattachmentmetadata) to fetch metadata such as size, name, and type of an existing attachment.

### Example request


```json

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

### Example response

The response will provide metadata about the file, such as its size, name, and type.


```json
{
    "request_id": "4cf641d4-dc42-4970-a1e6-8f7fb6c8785f",
    "data": {
        "metadata": {
            "file_size": 95299,
            "file_name": "c82a5350-19fe-11f0-959e-1373654fdef5.png",
            "file_type": "image/png"
        }
    }
}
```

Only basic metadata (name, type, size) is returned. No timestamps or status flags are included.

## Downloading an attachment

→ Use the [/messages/attachments/download endpoint](/demand/docs/open-api/demand-api/attachments/downloadmessageattachment) with the appropriate `conversation` and `attachment ID` to download a previously uploaded attachment.

### Example request


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

}
```

### Example response

The file is returned as a base64-encoded string in the response body.


```json
{
  "request_id": "773e2c0d-1ab3-449b-b88a-3d6b5ce09ae7",
  "data": {
    "conversation": "cc872746-77f2-5886-ba7c-17e0497241b5",
    "file_content": "/9j/4AAQSkZJRgABAQACWAJYAAD/2wCEAAgGBgc..."
  }
}
```

## Error handling

The API returns descriptive error messages for invalid requests. Validate input data before submitting requests to prevent issues.

| HTTP Code | Cause | Fix |
|  --- | --- | --- |
| 400 | File too large (>1MB) | Reduce file size |
| 400 | Mismatched `file_size` | Verify base64 length matches metadata |
| 400/415 | Unsupported file type | Use PNG/JPG |
| 404 | Invalid conversation/attachment ID | Check IDs |
| 429 | Rate limit exceeded | Wait & retry |


### Example - File too large

Attempting to upload a file larger than 1MB results in a 400 bad request error.


```json
{
  "errors": [
    {
      "id": 400,
      "message": {
        "error": "bad request",
        "message": "File size exceeds the 1MB limit"
      }
    }
  ]
}
```

**Fix:** Compress or resize image before uploading.

### Example - Mismatched file size

If the actual size of `file_content` does not match the declared `file_size`, a size mismatch error is returned.

#### Example request

The request below attempts to upload a file with a base64-encoded string, along with metadata describing the file's name, type, and size.


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

In this case, the `file_size` is set to **350 bytes**, while the actual file content size, as indicated by the base64-encoded string, does not match this value.

#### Example response

The system identifies the discrepancy between the declared file size (file_size) and the actual size of the base64-encoded content (`file_content`).

As a result, the API returns a 400 Bad Request error with a detailed message.


```json
{
    "request_id": "36a34bff-1353-4689-9169-3bcf361a4ff0",
    "errors": [
        {
            "id": 400,
            "message": {
                "error": "bad request",
                "message": "Request failed with code: 400, message: Content length is 35 but metadata size is 350"
            }
        }
    ]
}
```

#### How to fix it

To resolve this issue:

1. **Verify the file content size** - Ensure the size of the base64-encoded content matches the file size specified in the `file_size`.
2. **Re-encode the file if necessary** - If the file was manually encoded, verify the base64 string and re-encode the file to ensure the content and the metadata size align.
3. **Update metadata** - Adjust the `file_size` value to match the actual content length.


## Security and access

* Attachments are securely stored and can only be accessed by parties involved in the conversation.
* Files are not publicly accessible and require valid credentials and matching conversation context.
* Attachments currently do not expire, but we recommend downloading them soon after upload.


## Best Practices

✓ Validate file size before encoding.

✓ Upload only relevant images.

✓ Store downloads if multiple retrievals are needed.

✓ Keep Base64 content secure; do not share publicly.

Curious to know more?
* Get started - [Try out the messaging flows](/demand/docs/messaging/try-out-messages)
* Read the [Managing messages guide](/demand/docs/messaging/manage-messages) to learn how to send and receive messages.