---
title: "Send Media"
method: POST
path: "/whatsapp/send_media"
tags: ["WhatsApp"]
---

# Send Media

`POST /whatsapp/send_media`

## Request

- Base URL: `https://api.commpeak.com/textpeak/streams`
- URL: `https://api.commpeak.com/textpeak/streams/whatsapp/send_media`
- Auth: API key in header `Authorization`

Send a WhatsApp media message (image, document, audio, video, …) that references a file you have already uploaded with the **Upload file** endpoint. Pass the `media_id` returned by that upload.

Each entry sends one media message: set `recipient_phone` (and a `sender`, or rely on the stream default) for a new conversation, or `conversation_uuid` to reply into an existing one. `message_content` is stored with the message in the inbox but is not delivered as a caption.

**Response.** HTTP `200` with a `task_id` and one entry per message. `status` is `false` when any message failed: failed entries come first and carry `error` (hex code) and `details`; accepted entries carry `message_uuid` (and `conversation_uuid` on two-way channels). Match entries by `internal_id`. Final delivery status is sent asynchronously to your configured webhook.

**Authentication:** stream token in the `Authorization` header (see **Authentication** in the API Overview).

## Request body

- WhatsAppMediaRequest
  - `sender` string, nullable: Default WhatsApp Business sender phone number for every message.
  - `messages` WhatsAppMediaMessage[], required: The media messages to send, up to 250 per request.
    - `internal_id` string, nullable: Your identifier for the message. Echoed back in the response and in delivery webhooks (`internal_id`). Up to 36 characters are kept; longer values are cut. Not checked for uniqueness.
    - `sender` string, nullable: WhatsApp Business sender phone number; overrides the top-level `sender`.
    - `recipient_phone` string, nullable: Recipient phone number in international format, as a string. `+`, spaces, `-` and parentheses are removed before validation. Not needed when `conversation_uuid` or `contact.phone` identifies the recipient.
    - `conversation_uuid` string, nullable: Continue an existing conversation: the sender and recipient are taken from it. Two-way channels only (WhatsApp, Telegram, two-way SMS); ignored on one-way SMS.
    - `media` MediaRef, required
      - `media_id` string, required: The `media_id` returned by **Upload file**. Valid for 20 minutes after the upload has been processed; an unknown or expired ID fails the whole request with `0x17`.
    - `message_content` string, nullable: Text stored with the message in the inbox. It is not delivered as a caption.
    - `contact` Contact
      - `display_name` string, nullable: Name shown in the inbox. Defaults to `first_name` + `last_name`.
      - `first_name` string, nullable: First name.
      - `last_name` string, nullable: Last name.
      - `phone` string, nullable: Phone number; used as the recipient when `recipient_phone` is not set.
      - `email` string, nullable: E-mail address.
      - `external_id` string, nullable: Your CRM identifier for the contact; stored as the conversation lead ID.
      - `additional` object, nullable: Extra contact attributes. `additional.lead_id` takes precedence over `external_id`.

## Response `200`

Successful Response

- SendResponse
  - `status` boolean, required: `true` when every message was accepted; `false` when at least one failed. The HTTP status is `200` either way.
  - `task_id` string, required: Identifier of this request.
  - `messages` SendResultItem[], required: One entry per message. Failed messages are listed first, then accepted ones; match them by `internal_id`.
    - `internal_id` string, nullable: Your `internal_id`, echoed back (cut to 36 characters).
    - `message_uuid` string, nullable: Platform message identifier. Accepted messages only; use it with **Get message status**.
    - `conversation_uuid` string, nullable: The conversation the message belongs to. Two-way channels only.
    - `error` string, nullable: Failed messages only: the hex error code, for example `0x1` (invalid input), `0x19` (duplicate) or `0x31` (daily limit).
    - `details` string, nullable: Failed messages only: why it failed.

## Other responses

- `401`: Invalid token, or the token is not valid from this IP address.
- `402`: Payment required: the account balance is depleted (`0x41`).
- `403`: Missing token, blocked IP address, or the stream is not available (`0x11`, `0x16`, `0x21`, `0x22`).
- `422`: Validation Error
- `500`: The request was rejected as a whole (`0x0`): for example an unknown template or more than 250 items.

---

[API](https://skmtc.dev/commpeak/apis/commpeak-textpeak-streams-api.md) - [All operations](https://skmtc.dev/commpeak/apis/commpeak-textpeak-streams-api/llms.txt) - [OpenAPI document](https://skmtc.dev/commpeak/apis/commpeak-textpeak-streams-api/revisions/b9aaa8b4efa2?raw)
