> ## Documentation Index
> Fetch the complete documentation index at: https://knowledge.flowella.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Media in WhatsApp template headers: images and videos

> What media formats and sizes WhatsApp accepts in template headers, why YouTube links don't embed, and how to upload and reference media via Flowella.

A WhatsApp template can carry one piece of media in its header: an image, a video, or a document. Used well, it doubles the open and engagement rates of an otherwise text-only message. Used badly — wrong format, broken URL, mismatched MIME type — it causes the send to fail or the template to look amateurish.

This page is the practical reference for what works, what doesn't, and how to plumb the media through Flowella.

## Supported formats and limits

These are the formats and size limits Meta enforces on media in template headers (and elsewhere in WhatsApp Business Platform messages).

### Images

| Format | Extension        | MIME type    | Max size |
| ------ | ---------------- | ------------ | -------- |
| JPEG   | `.jpeg` / `.jpg` | `image/jpeg` | 5 MB     |
| PNG    | `.png`           | `image/png`  | 5 MB     |

Images must be **8-bit, RGB or RGBA**. WebP is **not** accepted in template headers (it's only valid in sticker messages, which are a separate message type).

**Recommended dimensions:** 1.91:1 aspect ratio, minimum 800×418 px. Square (1:1) images also render acceptably. Other aspect ratios are letterboxed by the WhatsApp client.

### Videos

| Format | Extension | MIME type    | Max size |
| ------ | --------- | ------------ | -------- |
| 3GPP   | `.3gp`    | `video/3gpp` | 16 MB    |
| MP4    | `.mp4`    | `video/mp4`  | 16 MB    |

Videos must use the **H.264 video codec** and **AAC audio codec**, with a **single audio stream or no audio**.

<Warning>
  Videos encoded with the H.264 **"High" profile and B-frames** are not supported by Android WhatsApp clients. Encode (or re-encode) with the H.264 **"Main" profile without B-frames**, or the **"Baseline" profile**, and place `moov` boxes before `mdat` boxes for broader compatibility.

  If using ffmpeg, the `-movflags faststart` flag handles the `moov`/`mdat` ordering.
</Warning>

### Documents

| Format               | Extension        | MIME type                                                                                                     | Max size |
| -------------------- | ---------------- | ------------------------------------------------------------------------------------------------------------- | -------- |
| PDF                  | `.pdf`           | `application/pdf`                                                                                             | 100 MB   |
| Microsoft Word       | `.doc` / `.docx` | `application/msword` / `application/vnd.openxmlformats-officedocument.wordprocessingml.document`              | 100 MB   |
| Microsoft Excel      | `.xls` / `.xlsx` | `application/vnd.ms-excel` / `application/vnd.openxmlformats-officedocument.spreadsheetml.sheet`              | 100 MB   |
| Microsoft PowerPoint | `.ppt` / `.pptx` | `application/vnd.ms-powerpoint` / `application/vnd.openxmlformats-officedocument.presentationml.presentation` | 100 MB   |
| Plain text           | `.txt`           | `text/plain`                                                                                                  | 100 MB   |

PDFs are the most reliably rendered across devices. Office documents work but require the recipient to have a compatible app installed; on a non-business mobile they usually open as previews.

## What doesn't work

<AccordionGroup>
  <Accordion title="YouTube and Vimeo embeds">
    You cannot embed a YouTube or Vimeo video in a template header. The header has to be an MP4 or 3GPP file that Meta can fetch and host.

    If you want to send a YouTube video, two options:

    1. **Put the YouTube link in the body or a URL button.** Tapping it opens the YouTube app or browser. The video preview shown in WhatsApp will be a static thumbnail.
    2. **Download the video and re-upload it as MP4.** Subject to your rights to redistribute the content, which usually means it has to be your own video.

    The latter is the way to get an actual in-conversation video preview.
  </Accordion>

  <Accordion title="GIFs">
    Animated GIFs (`.gif`) are not in the supported list. WhatsApp converts them server-side when shared peer-to-peer in the consumer app, but the Business Platform does not. Re-encode the GIF as an MP4 (which WhatsApp's mobile clients play with auto-play and no sound, the same way they show a GIF).
  </Accordion>

  <Accordion title="WebP images">
    WebP images are only valid for sticker messages, not template headers. Convert to JPEG or PNG before using as a header image.
  </Accordion>

  <Accordion title="HEIC photos straight from iPhone">
    iPhones default to saving photos in HEIC format, which is not on the supported list. Either change the iPhone setting to capture in JPEG, or convert HEIC to JPEG before upload.
  </Accordion>

  <Accordion title="Files above the size limit">
    A 6 MB image, an 18 MB video, or a 110 MB PDF will be rejected. Compress before upload. For images, the WhatsApp client also re-compresses on display, so a 4 MB photo isn't going to look meaningfully better than a 1 MB one on a phone screen.
  </Accordion>
</AccordionGroup>

## Two ways to attach media to a template

Meta supports two patterns for getting media into a template:

### Pattern 1: Media handle (recommended)

Upload the file via Meta's Media API, get back a **media handle**, and reference the handle when you send the template. Used by Flowella by default.

Benefits:

* Meta hosts the file, so there are no broken-URL failures at send time.
* Faster delivery because Meta doesn't have to fetch from an external URL.
* Works for the full size limits above.

The handle is valid for 30 days. If your template is going out repeatedly with the same media, Flowella refreshes the handle automatically before it expires.

### Pattern 2: Public HTTPS URL

Provide a URL to a publicly accessible file. Meta fetches it at send time.

This is useful when:

* The media changes per recipient (a personalised PDF, a per-order shipping label).
* The media is generated on the fly and you don't want to upload-per-send.

Caveats:

* The URL must be **publicly reachable** (no auth) and use **HTTPS with a valid certificate**.
* If the URL returns an error or is slow, the send fails.
* Meta caches the fetched file for a while; updating the file at the URL doesn't necessarily refresh what gets sent.

## How Flowella handles media upload

For most use cases, Flowella manages the media handle for you:

<Steps>
  <Step title="Add a header media file when building the template">
    In **Templates → Create**, choose **Image**, **Video**, or **Document** as the header type, then drag the file into the upload area.
  </Step>

  <Step title="Flowella validates the file">
    Format, size, and MIME type are checked before submission. If the file is unsupported, you see an error immediately rather than waiting for Meta to reject the template.
  </Step>

  <Step title="Flowella uploads to Meta and stores the handle">
    The file is uploaded via Meta's Media API. The returned handle is saved against the template.
  </Step>

  <Step title="Template submission includes the handle">
    When the template is submitted for approval, Meta sees the actual media (not a URL), so the review process can evaluate the visuals as part of approval.
  </Step>

  <Step title="Sends reuse the same handle">
    Until the template's header media changes, every send uses the same handle. Handles are automatically refreshed before expiry.
  </Step>
</Steps>

For per-recipient media (personalised PDFs, shipping labels), use the **Public URL** option in the template builder and pass the URL as a variable when triggering the send from a workflow or the API. See [Workflow Actions](/hubspot/workflow-actions).

## Designing for the WhatsApp viewport

A few design notes that don't appear in Meta's spec but matter in practice:

* **Text on images.** Keep it large and high-contrast. WhatsApp shows the image at roughly mobile-screen width, so anything smaller than about 14 px renders unreadable.
* **Safe area.** WhatsApp may crop or letterbox; keep critical content in the centre 80% of the image.
* **Brand consistency.** The header image and the WhatsApp display name and profile photo all sit close together — keep them visually consistent.
* **First frame of a video.** WhatsApp uses the first frame as the still preview before the video plays. Don't open with a black frame or a corporate logo splash; start on a meaningful image.
* **Document filename.** When sending a PDF or other document, the **filename** is visible to the recipient. Use a clear, descriptive name like `Acme-Order-12345-Receipt.pdf`, not `attachment.pdf`.

## Common errors and fixes

<AccordionGroup>
  <Accordion title="131053 — Mismatched MIME type">
    The file's actual MIME type doesn't match what was declared. Often happens when an iPhone-exported "JPEG" is actually HEIC, or when a tool renames a `.docx` to `.pdf` without converting.

    Fix: inspect the file (on macOS/Linux: `file -I yourfile.png`) and either re-export in the right format or change the extension to match.
  </Accordion>

  <Accordion title="Video plays without audio">
    The audio codec is something other than AAC, or there are multiple audio streams.

    Fix: re-encode with `ffmpeg -i input.mp4 -c:v libx264 -profile:v main -c:a aac -movflags faststart output.mp4`.
  </Accordion>

  <Accordion title="Video doesn't play on Android">
    Encoded with H.264 High profile and B-frames. Re-encode with Main or Baseline profile.
  </Accordion>

  <Accordion title="Public URL fetch failed">
    Meta can't reach the URL. Common causes: the URL requires authentication, the certificate is invalid, the server is slow to respond (timeout), or the URL returns a redirect instead of the file.

    Fix: test the URL with `curl -I` to confirm it returns 200 with the right content type, and that the certificate validates. Then re-try.
  </Accordion>

  <Accordion title="Image looks pixelated">
    The source is low-resolution, or it's been upscaled. WhatsApp doesn't re-process for sharpness; what you upload is what gets shown.

    Fix: upload at least 800 px on the long edge for a 1.91:1 image, and don't upscale a small source.
  </Accordion>
</AccordionGroup>

## Related guides

* [Template reference](/app/template-reference) — the full template structure that this media slots into
* [Templates](/app/templates) — step-by-step template creation in Flowella
* [Workflow Actions](/hubspot/workflow-actions) — passing per-recipient media URLs through HubSpot workflows
