---
title: "Send images, audio and PDFs with the WhatsApp API | D-API"
description: "How to send images, voice notes, video, documents and albums with the WhatsApp API, when to use a URL or base64, and how to download media customers send."
url: https://d-api.cloud/en/whatsapp-api-send-media
---

WhatsApp API guide

# How to send images, audio, video and documents with the WhatsApp API

In the WhatsApp API, each media type has its own endpoint, and they all follow the same logic: you pass the connection, the number and the file, as a public URL or base64. On the receiving side, media customers send arrives through the webhook and can be downloaded through the API.

By D-API engineering teamUpdated Sep 24, 20265 min read

## Why media changes the outcome of a conversation

An invoice as a PDF gets more done than a link to it. A product photo sells better than a description. A short voice note from a sales rep feels closer than three paragraphs. In business systems, the receipt a customer photographs and sends back needs to reach the finance team without anyone downloading and uploading files by hand.

A [WhatsApp API](https://d-api.cloud/en) handles both directions: your system attaches files to the messages it sends and receives the files customers send, ready to store or process.

## Sending endpoints by media type

| Type | Endpoint | File field | Useful options |
| --- | --- | --- | --- |
| Image | `/messages/send/image` | `image` | `caption` |
| Audio | `/messages/send/audio` | `audio` | `ptt` (voice note) |
| Video | `/messages/send/video` | `video` | `caption`, `ptv`, `gifPlayback` |
| Document | `/messages/send/document` | `document` | `fileName`, `mimetype` |
| Album | `/messages/send/album` | `media` (list) | `caption` per item |
| Sticker | `/messages/send/sticker` | `sticker` | \- |

Every route lives under `https://api.d-api.cloud/api/v1` and requires `sessionId` and `to`, with the number in international format without the plus sign, like `14155550123`.

## Sending examples

### A document with a friendly name

```
curl -X POST https://api.d-api.cloud/api/v1/messages/send/document \
  -H "Authorization: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "sessionId": "billing",
    "to": "14155550123",
    "document": "https://files.yourcompany.com/invoices/8812.pdf",
    "fileName": "invoice-september.pdf",
    "mimetype": "application/pdf"
  }'
```

Without `fileName`, the customer sees a generic name and gets suspicious. It is a small detail that cuts down on "is this a scam?" questions in support.

### Image, voice note and album with the Node SDK

```
import { DApi } from 'd-api-sdk'

const dapi = new DApi({ apiKey: process.env.DAPI_KEY })

await dapi.messages.sendImage({
  sessionId: 'store',
  to: '14155550123',
  image: 'https://cdn.yourcompany.com/products/blue-sneakers.jpg',
  caption: 'Back in stock in your size. Want me to hold a pair?',
})

await dapi.messages.sendAudio({
  sessionId: 'store',
  to: '14155550123',
  audio: 'https://cdn.yourcompany.com/audio/welcome.ogg',
  ptt: true,
})

await dapi.messages.sendAlbum({
  sessionId: 'store',
  to: '14155550123',
  media: [
    { type: 'image', url: 'https://cdn.yourcompany.com/products/front.jpg', caption: 'Front' },
    { type: 'image', url: 'https://cdn.yourcompany.com/products/side.jpg', caption: 'Side' },
  ],
})
```

The SDK is a thin client over the same REST API, so everything above also works with any HTTP client. More details on the [Node.js SDK](https://d-api.cloud/en/integrations/nodejs-sdk) page.

## Public URL or base64: how to decide

For single-file sends, the file field accepts two formats, and each has its place. In albums, items always go by URL.

-   **Public URL:** the file lives in storage or on a CDN and you pass the link. The request stays light, the same file serves many recipients and you are not pushing megabytes on every call. The link must respond without a login and without redirecting to an authentication page.
-   **Base64:** the content goes inside the JSON. It makes sense for files generated on the fly, like a receipt built by your system, or when the document holds sensitive data and you do not want it behind an accessible link. The cost is a larger payload.

If you go with a URL for sensitive data, use signed links with a short expiry. The API only needs to fetch the file at the moment of sending.

## Receiving and downloading media customers send

When a customer sends a photo, audio or document, the `messages.received` event reaches your [webhook](https://d-api.cloud/en/whatsapp-webhook) with `type` set to `image`, `audio`, `video`, `document` or `sticker`. The `media_url` field usually already carries a link to the stored file, and `media_data` carries type, size, caption, duration and, for audio, whether it is a voice note.

If you need the content as base64 (to send to OCR or a transcription model, for example) or the link came back empty, use the download endpoint. WhatsApp delivers media encrypted, and the endpoint decrypts it using the metadata that came with the event:

```
curl -X POST https://api.d-api.cloud/api/v1/media/download \
  -H "Authorization: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "sessionId": "billing",
    "direct_path": "<from the webhook>",
    "media_key": "<from the webhook>",
    "mimetype": "image/jpeg",
    "base64": true
  }'
```

Without `base64: true`, the file is saved to storage and the response returns `media_url`. For large files, the `async` parameter runs the download in the background. If you want to keep everything in your own bucket, you can use the native S3 or MinIO integration.

## Common mistakes when sending media

-   **A link that requires login or expires too fast:** the send fails or arrives empty. Test the URL in a private browser window.
-   **Audio without `ptt` when it should feel like a voice note:** the customer gets a file, not a message.
-   **Sending the same heavy media in bulk to lots of people:** besides the bandwidth cost, unusual sending volume is one of the signals that lead to bans. Read [how to avoid bans](https://d-api.cloud/en/avoid-whatsapp-ban) before automating campaigns.
-   **Processing media before answering the webhook:** download and handle the file in a worker, after returning 200.

If you want to send media from triggers in your system without writing code, see the [WhatsApp API for automation](https://d-api.cloud/en/whatsapp-api-for-automation). To combine media with clickable options, continue to [buttons and lists](https://d-api.cloud/en/whatsapp-buttons-and-lists).

## Frequently asked questions

### Can I send a PDF through the WhatsApp API?

Yes. Use the document endpoint and pass the file as a public URL or base64. Set fileName so the customer sees a readable name, like invoice-march.pdf, and mimetype when the type is not obvious from the extension.

### How do I make audio arrive as a recorded voice note?

Send it with ptt set to true. Without that field, the file shows up as an attached audio file with a file player. With ptt, it shows up as a voice bubble, just like audio recorded on the spot.

### Is it better to send media by URL or as base64?

A public URL is usually the best path: the request body stays small and the same file can serve many sends. Base64 makes sense when the file is generated on the fly and should not be exposed through a link.

### How do I receive the photos and audio customers send me?

They arrive on the incoming message webhook with the media type and, usually, a ready-to-use link in media\_url. When you need the file as base64 or the link is empty, use the media download endpoint with the metadata from the event.

### Can I send several photos in a single message?

Yes, with the album endpoint. You pass a list of images and videos by URL, each with an optional caption, and WhatsApp shows them grouped, just like when someone picks several photos from their gallery.

Try D-API's WhatsApp API3-day free trial, no credit card.[Start free trial](https://app.d-api.cloud/register?lang=en)

## Keep reading

-   [WhatsApp API guideWhatsApp buttons and lists](https://d-api.cloud/en/whatsapp-buttons-and-lists)
-   [WhatsApp API guideWhatsApp groups API](https://d-api.cloud/en/whatsapp-groups-api)
-   [WhatsApp API guideWhatsApp AI chatbot](https://d-api.cloud/en/whatsapp-ai-chatbot)
-   [WhatsApp API guideSelf-hosted vs managed](https://d-api.cloud/en/self-hosted-vs-managed-whatsapp-api)

## Try D-API's WhatsApp API

3-day trial with full access. No credit card, no lock-in.

[Start free trial](https://app.d-api.cloud/register?lang=en)[Read the docs](https://docs.d-api.cloud/)
