> ## Documentation Index
> Fetch the complete documentation index at: https://help.wizebot.com.br/llms.txt
> Use this file to discover all available pages before exploring further.

# Enviar mensagem

> Envia por qualquer canal conectado. O canal **deriva da conta remetente**, nunca do corpo: por isso não existe campo `channel` aqui.

O destinatário vem em uma das duas formas — `contact_id` (resolvido pela identidade que o contato tem *naquele canal*) ou `to` (endereço nativo). Exatamente uma das duas.

**Esta fase não inicia conversa.** Todo envio exige conversa existente com o destinatário; sem ela a resposta é `409 NO_OPEN_CONVERSATION`.



## OpenAPI

````yaml /openapi.json post /messages
openapi: 3.1.0
info:
  title: API WizeBot
  version: 3.0.0
  description: >-
    A API da WizeBot tem duas camadas sobre a **mesma base**
    `https://api.wizebot.com.br/v1`.


    **Contrato multicanal** — a camada neutra. Os mesmos endpoints falam com
    WhatsApp, com Telegram e com os canais que vierem depois. O canal não
    aparece na URL nem no corpo: ele vem da conta escolhida como remetente.
    Campos, códigos e mensagens em inglês.


    **API de WhatsApp** — a camada específica do canal, com o que só o WhatsApp
    tem. Continua existindo e não muda; quem já integrou com ela não precisa
    migrar.


    Toda requisição se autentica por cabeçalho. Não há autenticação por corpo
    nem por query string.
servers:
  - url: https://api.wizebot.com.br/v1
    description: Produção
security:
  - bearerAuth: []
tags:
  - name: Canais
    description: Contas de canal conectadas e o que cada uma aceita.
  - name: Mensagens
    description: Envio e status pelo contrato neutro, em qualquer canal.
  - name: WhatsApp · Mensagens
    description: Envio, status e modelos na camada específica de WhatsApp.
  - name: WhatsApp · Contatos
    description: Contatos e campos personalizados.
  - name: WhatsApp · Etiquetas
    description: Etiquetas e sua atribuição a contatos.
  - name: WhatsApp · Sequências
    description: Sequências agendadas de um contato.
  - name: WhatsApp · Conta
    description: Verificação da chave de API.
paths:
  /messages:
    post:
      tags:
        - Mensagens
      summary: Enviar mensagem
      description: >-
        Envia por qualquer canal conectado. O canal **deriva da conta
        remetente**, nunca do corpo: por isso não existe campo `channel` aqui.


        O destinatário vem em uma das duas formas — `contact_id` (resolvido pela
        identidade que o contato tem *naquele canal*) ou `to` (endereço nativo).
        Exatamente uma das duas.


        **Esta fase não inicia conversa.** Todo envio exige conversa existente
        com o destinatário; sem ela a resposta é `409 NO_OPEN_CONVERSATION`.
      operationId: enviarMensagem
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                channel_id:
                  type: string
                  description: >-
                    O `id` da conta de canal, vindo de `GET /channels`. É ele
                    que define o canal.
                contact_id:
                  type: string
                  description: >-
                    Identificador do contato na WizeBot. Use este **ou** `to`,
                    nunca os dois.
                to:
                  type: string
                  description: >-
                    Endereço nativo no canal — telefone no WhatsApp,
                    identificador de chat no Telegram.
                type:
                  type: string
                  enum:
                    - text
                    - image
                    - document
                    - audio
                    - video
                  default: text
                text:
                  type: string
                  description: Texto da mensagem. Obrigatório quando `type` é `text`.
                media_url:
                  type: string
                  description: URL pública da mídia. Obrigatório nos tipos de mídia.
                caption:
                  type: string
                  description: Legenda da mídia, onde o canal a aceita.
                filename:
                  type: string
                  default: document
                  description: Nome do arquivo, para `document`.
                client_message_id:
                  type: string
                  description: >-
                    Seu identificador do envio. Duas requisições com o mesmo
                    valor viram **um** envio só.
              required:
                - channel_id
            example:
              channel_id: 3fa85f64-5717-4562-b3fc-2c963f66afa6
              contact_id: 9c8b7a65-4321-4def-8abc-1234567890ab
              text: Seu pedido saiu para entrega.
              client_message_id: pedido-8842
      responses:
        '201':
          description: Mensagem aceita para envio.
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - data
                  - timestamp
                properties:
                  success:
                    type: boolean
                    description: Sempre `true` nas respostas de sucesso.
                  data:
                    type: object
                    properties:
                      message_id:
                        type: string
                        description: >-
                          Identificador da mensagem na WizeBot. Use-o na
                          consulta de status.
                      channel:
                        type: string
                        description: Canal por onde a mensagem sai, derivado da conta.
                      status:
                        type: string
                        description: >-
                          Sempre `queued`: o `201` diz que a mensagem foi
                          **aceita para envio**, não que chegou.
                  timestamp:
                    type: string
                    format: date-time
              example:
                success: true
                data:
                  message_id: 7f3e1a24-5b6c-4d8e-9f01-2a3b4c5d6e7f
                  channel: whatsapp
                  status: queued
                timestamp: '2026-09-09T17:15:20.453Z'
        '400':
          description: Erro de cliente. Veja os exemplos por código nomeado.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErroDaApi'
              examples:
                MISSING_PARAM:
                  summary: MISSING_PARAM
                  value:
                    success: false
                    statusCode: 400
                    timestamp: '2026-09-09T17:15:20.453Z'
                    path: /api/v1/messages
                    method: POST
                    message:
                      error: MISSING_PARAM
                      message: Exactly one of contact_id or to is required.
                    errorId: ERR-MTUD0DBO-KKRMP8
                INVALID_TYPE:
                  summary: INVALID_TYPE
                  value:
                    success: false
                    statusCode: 400
                    timestamp: '2026-09-09T17:15:20.453Z'
                    path: /api/v1/messages
                    method: POST
                    message:
                      error: INVALID_TYPE
                      message: >-
                        Invalid type. Must be one of: text, image, document,
                        audio, video.
                    errorId: ERR-MTUD0DBO-KKRMP8
                INVALID_MEDIA_URL:
                  summary: INVALID_MEDIA_URL
                  value:
                    success: false
                    statusCode: 400
                    timestamp: '2026-09-09T17:15:20.453Z'
                    path: /api/v1/messages
                    method: POST
                    message:
                      error: INVALID_MEDIA_URL
                      message: media_url must be a public http(s) URL.
                    errorId: ERR-MTUD0DBO-KKRMP8
                CHANNEL_MISMATCH:
                  summary: CHANNEL_MISMATCH
                  value:
                    success: false
                    statusCode: 400
                    timestamp: '2026-09-09T17:15:20.453Z'
                    path: /api/v1/messages
                    method: POST
                    message:
                      error: CHANNEL_MISMATCH
                      message: >-
                        Address looks like a 'whatsapp' address, but the channel
                        is 'telegram'.
                      details:
                        channel: telegram
                        implied_channel: whatsapp
                    errorId: ERR-MTUD0DBO-KKRMP8
        '401':
          description: '`UNAUTHORIZED` — Invalid or missing API key.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErroDaApi'
              examples:
                UNAUTHORIZED:
                  summary: UNAUTHORIZED
                  value:
                    success: false
                    statusCode: 401
                    timestamp: '2026-09-09T17:15:20.453Z'
                    path: /api/v1/messages
                    method: POST
                    message:
                      error: UNAUTHORIZED
                      message: Invalid or missing API key.
                    errorId: ERR-MTUD0DBO-KKRMP8
        '404':
          description: Erro de cliente. Veja os exemplos por código nomeado.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErroDaApi'
              examples:
                CHANNEL_NOT_FOUND:
                  summary: CHANNEL_NOT_FOUND
                  value:
                    success: false
                    statusCode: 404
                    timestamp: '2026-09-09T17:15:20.453Z'
                    path: /api/v1/messages
                    method: POST
                    message:
                      error: CHANNEL_NOT_FOUND
                      message: Channel not found.
                    errorId: ERR-MTUD0DBO-KKRMP8
                CONTACT_NOT_FOUND:
                  summary: CONTACT_NOT_FOUND
                  value:
                    success: false
                    statusCode: 404
                    timestamp: '2026-09-09T17:15:20.453Z'
                    path: /api/v1/messages
                    method: POST
                    message:
                      error: CONTACT_NOT_FOUND
                      message: Contact not found.
                    errorId: ERR-MTUD0DBO-KKRMP8
        '409':
          description: >-
            `NO_OPEN_CONVERSATION` — This channel requires an existing
            conversation with the recipient. Starting a conversation is not
            available in this contract yet.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErroDaApi'
              examples:
                NO_OPEN_CONVERSATION:
                  summary: NO_OPEN_CONVERSATION
                  value:
                    success: false
                    statusCode: 409
                    timestamp: '2026-09-09T17:15:20.453Z'
                    path: /api/v1/messages
                    method: POST
                    message:
                      error: NO_OPEN_CONVERSATION
                      message: >-
                        This channel requires an existing conversation with the
                        recipient. Starting a conversation is not available in
                        this contract yet.
                      details:
                        channel: telegram
                    errorId: ERR-MTUD0DBO-KKRMP8
        '422':
          description: Erro de cliente. Veja os exemplos por código nomeado.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErroDaApi'
              examples:
                RECIPIENT_NOT_ON_CHANNEL:
                  summary: RECIPIENT_NOT_ON_CHANNEL
                  value:
                    success: false
                    statusCode: 422
                    timestamp: '2026-09-09T17:15:20.453Z'
                    path: /api/v1/messages
                    method: POST
                    message:
                      error: RECIPIENT_NOT_ON_CHANNEL
                      message: Contact has no identity on channel 'telegram'.
                      details:
                        channel: telegram
                        contact_id: 9c8b7a65-4321-4def-8abc-1234567890ab
                    errorId: ERR-MTUD0DBO-KKRMP8
                UNSUPPORTED_CAPABILITY:
                  summary: UNSUPPORTED_CAPABILITY
                  value:
                    success: false
                    statusCode: 422
                    timestamp: '2026-09-09T17:15:20.453Z'
                    path: /api/v1/messages
                    method: POST
                    message:
                      error: UNSUPPORTED_CAPABILITY
                      message: >-
                        Channel 'telegram' does not support messages of type
                        'image'.
                      details:
                        channel: telegram
                        requested: image
                        supported:
                          - text
                    errorId: ERR-MTUD0DBO-KKRMP8
        '429':
          description: '`RATE_LIMITED` — Too many requests.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErroDaApi'
              examples:
                RATE_LIMITED:
                  summary: RATE_LIMITED
                  value:
                    success: false
                    statusCode: 429
                    timestamp: '2026-09-09T17:15:20.453Z'
                    path: /api/v1/messages
                    method: POST
                    message:
                      error: RATE_LIMITED
                      message: Too many requests.
                    errorId: ERR-MTUD0DBO-KKRMP8
        '500':
          description: '`SEND_FAILED` — Failed to send message.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErroDaApi'
              examples:
                SEND_FAILED:
                  summary: SEND_FAILED
                  value:
                    success: false
                    statusCode: 500
                    timestamp: '2026-09-09T17:15:20.453Z'
                    path: /api/v1/messages
                    method: POST
                    message:
                      error: SEND_FAILED
                      message: Failed to send message.
                    errorId: ERR-MTUD0DBO-KKRMP8
components:
  schemas:
    ErroDaApi:
      type: object
      description: >-
        Corpo de erro da API. `message` é um **objeto** com o código nomeado —
        não uma string.
      required:
        - success
        - statusCode
        - message
      properties:
        success:
          type: boolean
          description: Sempre `false`.
        statusCode:
          type: integer
        timestamp:
          type: string
          format: date-time
        path:
          type: string
          description: >-
            Caminho interno da requisição. Traz o prefixo `/api/v1` mesmo quando
            você chamou por `/v1`: o apelido é reescrito antes do roteamento.
        method:
          type: string
        message:
          type: object
          required:
            - error
            - message
          properties:
            error:
              type: string
              description: >-
                Código nomeado. É por ele que se trata o erro em código, nunca
                pelo texto.
            message:
              type: string
              description: Descrição em inglês, para leitura humana.
            details:
              type: object
              additionalProperties: true
              description: >-
                Contexto estruturado, presente nos códigos que o emitem —
                `CHANNEL_MISMATCH`, `NO_OPEN_CONVERSATION`,
                `RECIPIENT_NOT_ON_CHANNEL` e `UNSUPPORTED_CAPABILITY`.
        errorId:
          type: string
          description: Identificador do erro. Cite-o ao falar com o suporte.
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: >-
        Chave de API no cabeçalho `Authorization: Bearer SUA-CHAVE`.


        A API também aceita `x-api-key: SUA-CHAVE` e `Authorization: ApiKey
        SUA-CHAVE` — as três formas são equivalentes, inclusive para o limite de
        requisições.


        A chave dá acesso total à conta e é de servidor para servidor: não a use
        em navegador ou aplicativo móvel.

````