> ## Documentation Index
> Fetch the complete documentation index at: https://docs.60db.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# WhatsApp attachments

> Upload and download media through your workspace's connected number

Use your 60db API key with `whatsapp` scope. Meta credentials and temporary download URLs stay on the server.

## Upload

`POST /whatsapp/media` requires the same sending permission and active Starter, Creator or Pro platform plan as messages. Submit exactly one file and the 60db number UUID as multipart form data:

```bash theme={null}
curl --request POST 'https://api.60db.ai/whatsapp/media' \
  --header "Authorization: Bearer $SIXTYDB_API_KEY" \
  --form 'number_id=11111111-1111-4111-8111-111111111111' \
  --form 'file=@./order-photo.jpg;type=image/jpeg'
```

The `201` response has `success: true` and `data` containing `provider_id`, `type`, `mime_type`, `filename`, `file_size` and `expires_at`. Use `provider_id` in the matching [message content object](https://docs.60db.ai/api-reference/whatsapp/send-message.md). Uploaded IDs expire after 30 days. Uploading does not send a message or open the 24-hour reply window.

| Type | Supported formats | Maximum |
| - | - | - |
| Image | JPEG; 8-bit RGB/RGBA PNG | 5 MB |
| Audio | AAC, AMR, MP3, M4A/AAC, mono Ogg/Opus | 16 MB |
| Video | MP4/3GPP with H.264 and at most one AAC audio stream | 16 MB |
| Document | UTF-8 text, PDF, Word, Excel, PowerPoint | 100 MB |

Set the file's MIME type accurately. The API checks its size and content; Meta may reject files that do not meet its additional media requirements. Audio voice notes require mono Ogg/Opus. Sticker upload/sending is not exposed.

## Download

`GET /whatsapp/numbers/{number_uuid}/media/{provider_id}` requires read permission for the connected number. Media must already be recorded by an upload or a verified inbound message for that number and workspace. Inbound IDs expire after seven days.

```bash theme={null}
curl 'https://api.60db.ai/whatsapp/numbers/11111111-1111-4111-8111-111111111111/media/123456789' \
  --header "Authorization: Bearer $SIXTYDB_API_KEY" \
  --output attachment.jpg
```

A successful response is the binary file, with its MIME type, attachment filename and `Cache-Control: private, no-store`. It is not a JSON envelope. The server obtains a fresh provider URL for each request and verifies size and SHA-256 before returning the file. API keys stay in request headers; do not put them in image or audio URLs.

A provider HTTP 401/403 during the binary download triggers the shared access probe. A confirmed invalid token stops the captured connection and returns `META_TOKEN_REVOKED`. A valid, matching-app probe with a verified missing management or messaging grant stops it with `META_PERMISSIONS_MISSING`. Granted permissions, indeterminate/malformed responses and failed probes preserve the connection and return the sanitized download failure. Download URLs, provider response bodies and authorization headers are not exposed. An old download failure cannot disable a replacement token.

In the dashboard, select an attachment to load its preview, play audio/video with native controls, or save it. Reply attachments retain the same send idempotency key after an interrupted 60db API response.

## Errors

| HTTP | Code | Recovery |
| - | - | - |
| 400 | `MEDIA_FILE_REQUIRED` | Submit one file in the `file` field |
| 400 | `MEDIA_TYPE_UNSUPPORTED` / `MEDIA_FORMAT_INVALID` | Use a supported MIME type, content and codecs |
| 400 | `MEDIA_TYPE_MISMATCH` | Match the message type to the uploaded file |
| 413 | `MEDIA_TOO_LARGE` | Reduce the file to the type's limit |
| 404 | `MEDIA_NOT_FOUND` | Use an ID recorded for this number and workspace |
| 410 | `MEDIA_EXPIRED` | Upload the file again |
| 409 | `NUMBER_DISCONNECTED` | Reconnect the number |
| 409 | `META_TOKEN_REVOKED` | Reconnect after confirmed revoked/expired account access |
| 409 | `META_PERMISSIONS_MISSING` | Reconnect and grant required management/messaging access |
| 502 | `MEDIA_DOWNLOAD_FAILED` / `MEDIA_INTEGRITY_FAILED` | Retry the download; an incomplete file is not returned |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.