# Get message media

> Get a short-lived download URL for the image, video, audio, document, or sticker of a message.

`GET https://api-connect.nxiom.com/api/v1/messaging/messages/{messageId}/media`

Media files are never linked from message objects or webhooks. Request a URL when you need the file, download it right away, and don't store the URL.

## Authorization

Requires `whatsapp.send` for the media of messages you sent. The media of messages your customers sent you needs `whatsapp.full_access`: with a send-only key, those messages return `404`. WhatsApp must be turned on for your organization.

## Path parameters

| Field | Type | Description |
| --- | --- | --- |
| `messageId` | string · required | ID of a message with media, starting with `msg_`: an image, video, audio, document, or sticker, or a template with a media header. |

## Query parameters

| Field | Type | Description |
| --- | --- | --- |
| `expiresInSeconds` | integer · optional | How long the URL works, from `30` to `3600` seconds. Default `300`. |

## Request

### cURL

```shell
curl "https://api-connect.nxiom.com/api/v1/messaging/messages/msg_example/media?expiresInSeconds=300" \
  -H "Authorization: Bearer $NEXIOM_API_KEY"
```

### Node.js

```typescript
const apiKey = process.env.NEXIOM_API_KEY;
if (!apiKey) throw new Error('Set NEXIOM_API_KEY');

const response = await fetch(
  'https://api-connect.nxiom.com/api/v1/messaging/messages/msg_example/media?expiresInSeconds=300',
  {
    method: 'GET',
    headers: {
      Authorization: `Bearer ${apiKey}`,
    },
  },
);

const result = await response.json();
if (!response.ok) {
  throw new Error(result.message ?? `HTTP ${response.status}`);
}
console.log(result);
```

### PHP

```php
<?php

$apiKey = getenv('NEXIOM_API_KEY');
if (!$apiKey) {
    throw new RuntimeException('Set NEXIOM_API_KEY');
}

$request = curl_init("https://api-connect.nxiom.com/api/v1/messaging/messages/msg_example/media?expiresInSeconds=300");
curl_setopt_array($request, [
    CURLOPT_CUSTOMREQUEST => "GET",
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_HTTPHEADER => [
        "Authorization: Bearer $apiKey",
    ],
]);

$raw = curl_exec($request);
$status = curl_getinfo($request, CURLINFO_HTTP_CODE);
$error = curl_error($request);
curl_close($request);

if ($raw === false) {
    throw new RuntimeException($error);
}
$result = json_decode($raw, true, 512, JSON_THROW_ON_ERROR);
if ($status >= 400) {
    throw new RuntimeException($result["message"] ?? "HTTP $status");
}
print_r($result);
```

## Response

HTTP `200`. Example identifiers below are illustrative.

| Field | Type | Description |
| --- | --- | --- |
| `message_id` | string | The message ID. |
| `url` | string | Where to download the file: a short-lived URL, or the link you sent the file by. |
| `expires_at` | string or null | When `url` stops working. `null` for a link you sent the file by. |
| `mime_type` | string or null | The file type, such as `image/jpeg`. |
| `size_bytes` | number or null | The file size in bytes. `null` for a link you sent the file by. |
| `filename` | string or null | The file name, when known. |

### 200 OK

A download URL for a photo a customer sent.

```json
{
  "message": "Media URL created",
  "data": {
    "message_id": "msg_example",
    "url": "https://files.example.com/whatsapp/msg_example?signature=example",
    "expires_at": "2026-10-14T10:08:00.000Z",
    "mime_type": "image/jpeg",
    "size_bytes": 48213,
    "filename": "msg_example.jpeg"
  }
}
```

### 400 Bad Request

The request is invalid. Correct it before retrying; `details` lists the failing fields.

```json
{
  "error": "invalid_argument",
  "message": "Request doesn't match the schema",
  "correlationId": "req_example",
  "details": {
    "context": "body",
    "issues": []
  }
}
```

### 401 Unauthorized

The API key is missing, malformed, revoked, or expired.

```json
{
  "error": "unauthorized",
  "message": "Invalid API key",
  "correlationId": "req_example"
}
```

### 403 Forbidden

The API key lacks whatsapp.send, or WhatsApp is not turned on for your organization (code: FEATURE_NOT_AVAILABLE).

```json
{
  "error": "not_allowed",
  "message": "Missing required API key permissions: whatsapp.send",
  "correlationId": "req_example"
}
```

### 404 Not Found

No message with this ID exists in the key's project, it was deleted after 30 days, or a customer sent it and the key lacks whatsapp.full_access (message_not_found). Or the message has no media file (whatsapp_media_not_found).

```json
{
  "error": "not_found",
  "code": "whatsapp_media_not_found",
  "message": "This message has no media.",
  "correlationId": "req_example"
}
```

### 409 Conflict

The file isn't available. With the code whatsapp_media_pending, a file a customer sent is still being downloaded from WhatsApp: try again shortly, or wait for the whatsapp.message.received webhook. With whatsapp_media_unavailable, it could not be downloaded and never will be.

```json
{
  "error": "conflict",
  "code": "whatsapp_media_pending",
  "message": "The media of this message is still being stored. Try again shortly.",
  "correlationId": "req_example"
}
```

## Errors

| Status | `code` | Returned when |
| --- | --- | --- |
| `400` | none | `expiresInSeconds` is not a whole number from `30` to `3600`. |
| `401` | none | The API key is missing, malformed, revoked, or expired. |
| `403` | none | The key lacks the `whatsapp.send` permission. |
| `403` | `FEATURE_NOT_AVAILABLE` | WhatsApp is not turned on for your organization. |
| `404` | `message_not_found` | No message with this ID exists in the key's project, it was deleted after 30 days, or it is a received message and the key lacks `whatsapp.full_access`. |
| `404` | `whatsapp_media_not_found` | The message has no media file, or the file was deleted. |
| `409` | `whatsapp_media_pending` | The file a customer sent is still being downloaded from WhatsApp. |
| `409` | `whatsapp_media_unavailable` | The file a customer sent could not be downloaded from WhatsApp. |

---

Source: https://connect.nxiom.com/docs/api/messaging/media
