# Media

You can send messages containing audio, documents, images, stickers, or videos to your customers.

When you send a message that includes media, you need to provide either the ID of the uploaded media or a link to the media in the request body.&#x20;

You also need to specify the type of media. Possible types: `audio`, `document`, `image`, `sticker`, or `video`.&#x20;

{% hint style="info" %}
You can only send a text message within the customer service window. Outside the customer service window, you will need to start a new conversation by [Sending a Template Message](https://docs.360dialog.com/docs/resources/templates).
{% endhint %}

## Media IDs vs Media links

There are two ways to send media messages:

* **IDs (recommended)** - To use an ID, you must first [upload the media](https://docs.360dialog.com/docs/waba-messaging/media/upload-retrieve-or-delete-media#upload-media) to obtain the ID. Afterward, you can use  `media_id` from the response to attach the media to your messages. By following this approach, you can ensure that the media file is processed accurately without causing any delays or latencies during send-outs.
* **Links (not recommended)** - you supply HTTP or HTTPS link to a file. You will need to use a link that directs to the file itself. Some suggested platforms that offer this type of link are Google Cloud Storage Bucket, AWS S3 Bucket. When sending messages with media such as images, videos, or audio files, it is important to ensure that they are not heavy, as processing heavy media files at once can cause delays in transmission and lead to issues with message delivery. To set up caching, refer to "Media links: How to set up caching" below.&#x20;

Either `id` or `link` is required, but should not be used at the same time.

## How to send a media message

<mark style="color:green;">`POST`</mark> `https://waba-v2.360dialog.io/messages`

#### Request Body

| Name                | Type   | Description                               |
| ------------------- | ------ | ----------------------------------------- |
| recipient\_type     | string | individual                                |
| SPECIFIC PARAMETERS | String |                                           |
| type                | string |                                           |
| to                  | string | wa\_id of the contact you want to message |

**Example:**

Sending media messages using **Media ID**:

```json
{
  "messaging_product": "whatsapp",
  "recipient_type": "individual",
  "to": "PHONE-NUMBER",
  "type": "image",
  "image": {
    "id" : "MEDIA-OBJECT-ID"
  }
}
```

Sending media messages using **Media link**:

```json
{
  "messaging_product": "whatsapp",
  "recipient_type": "individual",
  "to": "PHONE-NUMBER",
  "type": "image",
  "image": {
    "link" : "https://IMAGE_URL"
  }
}
```

In the case of an unsuccessful response, a callback is sent to your Webhook URL, even though the response will yield a message ID similar to a successful message send.&#x20;

<details>

<summary>Media links: How to set up caching</summary>

As mentioned before, Media ID is the recommended way of sending Media files.&#x20;

But if you still need to use Media link, you can instruct Meta to cache your asset for reuse with future messages by including the headers below in your server response when the asset is requested. If none of these headers are included, Meta will not cache your asset.

```json
Cache-Control: <CACHE_CONTROL>
Last-Modified: <LAST_MODIFIED>
ETag: <ETAG>
```

**Cache-Control**

The `Cache-Control` header tells Meta how to handle asset caching. They support the following directives:

* `max-age=n`: Indicates how many seconds (`n`) to cache the asset. The cached asset will be reused in subsequent messages until this time is exceeded, after which the asset will be requested again, if needed. Example: `Cache-Control: max-age=604800`.
* `no-cache`: Indicates the asset can be cached but should be updated if the `Last-Modified` header value is different from a previous response. Requires the `Last-Modified` header. Example: `Cache-Control: no-cache`.
* `no-store`: Indicates that the asset should not be cached. Example: `Cache-Control: no-store`.
* `private`: Indicates that the asset is personalized for the recipient and should not be cached.

**Last-Modified**

Indicates when the asset was last modified. Used with `Cache-Control: no-cache`. If the `Last-Modified` value is different from a previous response and `Cache-Control: no-cache` is included in the response, Meta updates their cached version of the asset with the asset in the response. Example: `Date: Tue, 22 Feb 2025 22:22:22 GMT`.

**ETag**

The `ETag` header is a unique string that identifies a specific version of an asset. Example: `ETag: "33a64df5"`. This header is ignored unless both `Cache-Control` and `Last-Modified` headers are not included in the response. In this case, we will cache the asset according to our own, internal logic (which Meta does not disclose).

**Sample Response with Headers**

```json
HTTP/1.1 200 OK
Content-Type: image/png
Content-Length: 1024
Date: Tue, 22 Feb 2025 22:22:22 GMT
ETag: "33a64df5"
Cache-Control: max-age=604800

<IMAGE_PAYLOAD>
```

</details>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.360dialog.com/docs/messaging/media.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
