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

# Upload de mídia

> Obtenha o header_handle para templates com HEADER de imagem, vídeo ou documento

## Conceituação

A Meta **não aceita o arquivo direto** na criação do template. Ela exige um `header_handle` produzido pela Resumable Upload API, que depende do token da aplicação — por isso o upload passa por aqui, e não pelo seu frontend.

Este endpoint recebe o arquivo e devolve o handle pronto para usar.

## Quando você precisa disso

Somente quando o template tem um componente `HEADER` do tipo `IMAGE`, `VIDEO` ou `DOCUMENT`. Templates com header de texto, ou sem header, não precisam de upload.

## Fluxo

<Steps>
  <Step title="Suba o arquivo">
    `POST /whatsapp/businesses/{wabaId}/templates/media` com `multipart/form-data`, campos `file` e `type`.
  </Step>

  <Step title="Guarde o handle">
    A resposta traz o handle no campo `h`.
  </Step>

  <Step title="Use no componente HEADER">
    Passe o handle como `example` do HEADER em [Criar template](/templates/create-template):

    ```json theme={null}
    {
      "type": "HEADER",
      "format": "IMAGE",
      "example": { "header_handle": ["4::aW1hZ2UvanBlZw==:ARZ..."] }
    }
    ```
  </Step>
</Steps>

<Warning>
  O handle tem validade. Suba o arquivo e crie o template na mesma sessão — não guarde o handle para usar dias depois.
</Warning>

<Note>
  Além de `h`, a API aceita o handle nas chaves `handle`, `header_handle`, `headerHandle` e `mediaHandle`. Use `h`, que é a forma canônica.
</Note>

## Pré-requisito de configuração

O upload depende do **App ID** e do **App Secret** da Meta cadastrados na conta. Sem isso a chamada retorna `422` com `MISSING_APP_CREDENTIALS`.

Isso é configurado no painel, em **Segurança** — não há endpoint público para cadastrar as credenciais do app. Veja também [Origens do SDK](/channels/sdk-info), que trata do outro pré-requisito do fluxo via SDK.

## Limites

| Item                | Valor          |
| ------------------- | -------------- |
| Tamanho máximo      | 100 MB         |
| Campos obrigatórios | `file`, `type` |


## OpenAPI

````yaml pt/templates/openapi.json POST /whatsapp/businesses/{wabaId}/templates/media
openapi: 3.1.0
info:
  title: Omni Z-API - Templates API
  description: API para gerenciamento de templates de mensagem do WhatsApp Business
  version: 1.0.0
servers:
  - url: https://api.omni.z-api.io
security:
  - bearerAuth: []
paths:
  /whatsapp/businesses/{wabaId}/templates/media:
    post:
      tags:
        - Templates
      summary: Upload de mídia para template
      description: >-
        Envia o arquivo do HEADER de mídia e devolve o `header_handle` exigido
        pela Meta.


        A Meta não aceita o arquivo direto na criação do template: ela exige o
        handle da Resumable Upload API, que depende do token da aplicação. Este
        endpoint faz esse intermédio.
      operationId: uploadTemplateMedia
      parameters:
        - name: wabaId
          in: path
          required: true
          description: ID do WABA (obtido via Listar WABAs)
          schema:
            type: string
            example: '428083093730937'
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              required:
                - file
                - type
              properties:
                file:
                  type: string
                  format: binary
                  description: >-
                    Arquivo do header (imagem, vídeo ou documento). Limite de
                    100 MB
                type:
                  type: string
                  description: >-
                    MIME type do arquivo (ex: `image/jpeg`, `video/mp4`,
                    `application/pdf`)
                  example: image/jpeg
      responses:
        '200':
          description: Upload concluído
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TemplateMediaResponse'
              example:
                h: 4::aW1hZ2UvanBlZw==:ARZ...:e:1770000000:...
        '400':
          description: Requisição inválida — arquivo vazio ou `type` ausente
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Token inválido ou ausente.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '413':
          description: Arquivo maior que 100 MB
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '422':
          description: >-
            A conta não tem App ID e App Secret da Meta configurados
            (`MISSING_APP_CREDENTIALS`)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '502':
          description: >-
            A Meta recusou o upload (`META_REFUSED`) ou a configuração do app
            não pôde ser lida (`CONFIG_UNREACHABLE`)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
components:
  schemas:
    TemplateMediaResponse:
      type: object
      properties:
        h:
          type: string
          description: >-
            Handle a ser usado como `example` do componente HEADER na criação do
            template
    Error:
      type: object
      properties:
        error:
          type: integer
          description: Código do erro
        message:
          type: string
          description: Descrição do erro
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: Secret Key gerada no painel de Segurança do Omni Z-API

````