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

# Enviar mensagem para um número (cria conversa se preciso)

> Envia uma mensagem direto pra um número de telefone, criando o contato e a conversa (ticket) automaticamente quando ainda não existem. A conexão de saída é escolhida nesta ordem: `whatsappId`, se informado; senão `whatsappName`; senão a conexão padrão configurada na sua conta (não por token); senão a primeira conexão whatsapp/waba CONECTADA da sua conta, pelo menor id; senão a primeira conexão whatsapp/waba existente, pelo menor id (o campo `isDefault` de /v1/connections não entra nessa escolha). Envie pelo menos um entre `body`, `medias` (multipart) ou `templateData`; fora da janela de 24h do WABA só templates aprovados são entregues. `contactName` só é usado se o contato for criado agora. Com `saveOnTicket=false` o envio é feito à parte do fluxo normal de atendimento (fire-and-forget), mas em conexões WABA o ticket criado/reaproveitado é um ticket normal, `status: "open"`, e aparece no painel igual a qualquer outra conversa — não é invisível. Nesse modo, `medias` é ignorado (só body/templateData chegam ao envio) e o `id` de cada mensagem no retorno pode vir `null`. O `status` de cada mensagem no retorno pode ser `queued`, `sent`, `server_ack`, `delivered`, `read`, `failed`, `received` ou `unknown`. Número ausente devolve 400 ERR_NUMBER_REQUIRED; número sem dígitos válidos, 400 ERR_NUMBER_INVALID; nenhum conteúdo, 400 ERR_MISSING_CONTENT; conexão informada que não existe na sua conta, 404 ERR_CONNECTION_NOT_FOUND; nenhuma conexão disponível, 404 ERR_NO_CONNECTION_AVAILABLE; conexão de canal diferente de whatsapp/waba, 400 ERR_UNSUPPORTED_CHANNEL. Requer escopo `messages:send`.



## OpenAPI

````yaml /openapi/wapi-v1.pt.json post /v1/messages/send
openapi: 3.1.0
info:
  title: Whatix — API do Chat
  version: 1.0.0
  description: >-
    API pública do Whatix para integrar seus sistemas ao atendimento: enviar e
    ler mensagens, gerenciar contatos e tags, ler e mover cards de pipeline e
    disparar flows.


    ## Base URL

    Cada cliente tem a própria instância: `https://<sua-instancia>/wapi`. O
    playground usa a variável `instance`; o botão **Documentação** da tela *API
    do Chat* já a preenche.


    ## Autenticação

    `Authorization: Bearer wtx_live_…`. Tokens são criados por um admin em *API
    → Tokens*, com validade opcional e **escopos** no formato `recurso:ação`:


    | Recurso | Escopos | Endpoints |

    |---|---|---|

    | conversations | read | GET /v1/conversations |

    | messages | read, send | GET …/messages, GET /v1/messages/{id}/status ·
    POST /v1/messages/send, POST …/messages |

    | connections | read | GET /v1/connections |

    | contacts | read, write | GET/POST/PUT /v1/contacts…, GET /v1/tags |

    | cards | read, write | GET /v1/cards…, GET /v1/pipelines, GET
    /v1/lost-reasons · POST /v1/cards, PATCH …/stage |

    | flows | trigger | POST /v1/flows/trigger |


    Um escopo `write` inclui o `read` correspondente.


    ## Erros

    Sempre JSON: `{ "error": "<texto>", "code": "ERR_…" }`. Trate pelo `code`;
    `error` é texto pra humanos.


    | Código | HTTP | Quando acontece |

    |---|---|---|

    | `ERR_TOKEN_MISSING` | 401 | Header Authorization ausente. Envie
    `Authorization: Bearer wtx_live_…`. |

    | `ERR_TOKEN_INVALID` | 401 | O token não existe ou está mal formado. Gere
    um novo na tela API do Chat → Tokens. |

    | `ERR_TOKEN_REVOKED` | 401 | O token foi revogado no painel. Crie outro. |

    | `ERR_TOKEN_EXPIRED` | 401 | Passou da validade definida na criação. Crie
    outro ou rotacione antes de expirar. |

    | `ERR_SCOPE_MISSING` | 403 | O token é válido mas não tem o escopo exigido
    pelo endpoint. Um escopo `x:write` satisfaz `x:read`. |

    | `ERR_RATE_LIMITED` | 429 | Mais de 120 requisições por minuto com o mesmo
    token. Aguarde os segundos de `Retry-After`. |

    | `ERR_MISSING_CONTENT` | 400 | O envio precisa de pelo menos um entre
    `body`, `medias` (multipart) ou `templateData`. |

    | `ERR_NUMBER_REQUIRED` | 400 | O campo `number` é obrigatório. |

    | `ERR_NUMBER_INVALID` | 400 | O número não tem dígitos válidos após
    normalização. Use E.164 sem `+` (ex.: 5534999990000). |

    | `ERR_CONNECTION_NOT_FOUND` | 404 | `whatsappId`/`whatsappName` não
    corresponde a uma conexão desta conta. |

    | `ERR_NO_CONNECTION_AVAILABLE` | 404 | A conta não tem conexão padrão
    ativa. Informe `whatsappId` ou configure a conexão padrão no painel. |

    | `ERR_UNSUPPORTED_CHANNEL` | 422 | A conexão escolhida não é WhatsApp. Só
    canais `whatsapp` e `waba` enviam pela API. Em POST /v1/messages/send
    devolve 400; em POST /v1/flows/trigger, 422. |

    | `ERR_NO_TICKET_FOUND` | 404 | Conversa (ticket) inexistente ou de outra
    conta. |

    | `ERR_MISSING_NUMBER` | 400 | `number` é obrigatório no upsert de contato.
    |

    | `ERR_NUMBER_NOT_ON_WHATSAPP` | 422 | Com `validateNumber=true`, o número
    não existe no WhatsApp. |

    | `ERR_WHATSAPP_NOT_FOUND` | 404 | `whatsappId` informado não é uma conexão
    desta conta. |

    | `ERR_NO_CONTACT_FOUND` | 404 | Contato inexistente ou de outra conta. |

    | `ERR_NUMBER_IMMUTABLE` | 400 | `PUT /v1/contacts/{id}` não aceita
    `number`. Corrija o número pelo painel. |

    | `ERR_INVALID_TAG_IDS` | 400 | `tagIds` ausente ou não é array. Tags de
    outra conta são ignoradas em silêncio. |

    | `ERR_INVALID_TAGMODE` | 400 | A conta não usa etiquetas de contato (modo
    de tags configurado só para conversas). Ajuste o modo de tags no painel. |

    | `ERR_INVALID_DATE_FILTER` | 400 | Filtro de data sem offset de fuso (use
    `2026-09-01T00:00:00-03:00`). |

    | `ERR_NO_CARD_FOUND` | 404 | Card inexistente ou de outra conta. |

    | `ERR_CONTACT_IDENTIFIER_REQUIRED` | 400 | Informe exatamente um entre
    `contactId` e `phone` ao criar card. |

    | `ERR_PIPELINE_NOT_FOUND` | 404 | `pipelineId` inexistente ou de outra
    conta. |

    | `ERR_STAGE_REQUIRED` | 400 | `stageId` é obrigatório ao mover card. |

    | `ERR_STAGE_NOT_FOUND` | 404 | `stageId` inexistente ou de outra conta. |

    | `ERR_STAGE_NOT_IN_PIPELINE` | 422 | A etapa existe, mas pertence a outro
    pipeline. Mover entre pipelines não é permitido. |

    | `ERR_SOURCE_NOT_FOUND` | 404 | `sourceId` (origem do card) inexistente ou
    de outra conta. |

    | `ERR_SOURCE_REQUIRED_FOR_STAGE` | 400 | A etapa escolhida exige uma origem
    (`sourceId`). Informe-a ou use uma etapa que não exija. |

    | `ERR_FLOW_ID_AND_WHATSAPP_ID_REQUIRED` | 400 | `flowId` e `whatsappId` são
    obrigatórios. |

    | `ERR_VARIABLES_MUST_BE_OBJECT` | 400 | `variables` precisa ser um objeto
    JSON (chave → valor). |

    | `ERR_FLOW_NOT_FOUND` | 404 | Flow inexistente ou de outra conta. |

    | `ERR_FLOW_NOT_EXECUTABLE` | 422 | Flow inativo, despublicado ou sem nós.
    Publique-o no FlowBuilder. |

    | `ERR_TICKET_IN_HUMAN_SERVICE` | 409 | O contato está em atendimento humano
    ativo; o flow não é disparado pra não atropelar o atendente. |

    | `ERR_FEATURE_NOT_AVAILABLE` | 403 | Recurso não incluído no seu plano
    (middleware hasFeature). |

    | `ERR_STORAGE_LIMIT_REACHED` | 403 | Limite de armazenamento da instância
    atingido; envio de mídia bloqueado. |

    | `ERR_DUPLICATED_CONTACT` | 400 | Já existe outro contato com esse número.
    |

    | `ERR_CONTACT_NUMBER_IS_LID` | 400 | Número é um identificador @lid do
    WhatsApp, não um telefone. |


    Erros levantados pelos middlewares `hasFeature`/`checkStorage`
    (`ERR_FEATURE_NOT_AVAILABLE`, `ERR_STORAGE_LIMIT_REACHED`) vêm sem `code`
    hoje.


    ## Rate limit

    120 requisições por minuto por token. Toda resposta traz
    `X-RateLimit-Limit`, `X-RateLimit-Remaining` e `X-RateLimit-Reset` (epoch em
    segundos). Ao exceder: 429 com `Retry-After` em segundos.


    ## Paginação

    Listas aceitam `pageNumber` (1-based) e `pageSize` (default 40, máx. 100;
    mensagens: default 100, máx. 200) e devolvem `count` e `hasMore`. Valor de
    `pageSize` acima do máximo não dá erro — é limitado ao máximo em silêncio.
    Filtros de data (`createdAtAfter`/`createdAtBefore`,
    `closedAtAfter`/`closedAtBefore`) são inclusivos nos dois limites.


    ## Números

    E.164 **sem** `+`: DDI + DDD + número (`5534999990000`).


    ## Perguntas frequentes

    - **`wtx_test_` vs `wtx_live_`?** Só o prefixo do token muda — hoje não há
    diferença de comportamento entre os dois ambientes; os dois funcionam do
    mesmo jeito na API.

    - **Como listo as origens (`sourceId`)?** Não existe endpoint pra isso. Os
    nomes de origem vêm dentro de cada card (campo `source`) e são cadastrados
    no painel.

    - **Quais filtros aceitam múltiplos valores (CSV)?** Só `status`,
    `contactTagId` e `notContactTagId` de GET /v1/cards. `stageId`, `sourceId`,
    `pipelineId` e os demais IDs são sempre um único inteiro.

    - **Como contar cards por etapa sem paginar tudo?** Use `pageSize=1` com o
    filtro de `stageId` desejado e leia só o `count` da resposta.

    - **GET /v1/pipelines mostra todos os pipelines?** Sim — todos os pipelines
    da sua conta, sem filtro de visibilidade por usuário.

    - **O que a API devolve num erro interno (500)?** `{ "error": "Internal
    server error" }`, sem `code`. Trate como transitório e repita com backoff.

    - **O que é `stageEnteredAt`?** Quando o card entrou na etapa (`stage`)
    atual — é o que a plataforma usa pra medir estagnação.
servers:
  - url: https://{instance}/wapi
    description: Sua instância Whatix
    variables:
      instance:
        default: sua-instancia.whatix.cloud
        description: Domínio da sua instância (sem https://)
security:
  - bearerAuth: []
tags:
  - name: Conversas
    description: >-
      Conversas (tickets) da sua instância: listar, filtrar por status, fila,
      atendente.
  - name: Mensagens
    description: Enviar texto, mídia e templates; ler o histórico e o status de entrega.
  - name: Conexões
    description: Canais conectados (WhatsApp/WABA) e qual é o padrão de envio.
  - name: Contatos
    description: Cadastro por número, upsert idempotente, tags.
  - name: Cards
    description: >-
      Cards de pipeline (o que o painel chama de Pipelines): pipelines, etapas,
      motivos de perda.
  - name: Flows
    description: Disparar um flow publicado do FlowBuilder para um número.
paths:
  /v1/messages/send:
    post:
      tags:
        - Mensagens
      summary: Enviar mensagem para um número (cria conversa se preciso)
      description: >-
        Envia uma mensagem direto pra um número de telefone, criando o contato e
        a conversa (ticket) automaticamente quando ainda não existem. A conexão
        de saída é escolhida nesta ordem: `whatsappId`, se informado; senão
        `whatsappName`; senão a conexão padrão configurada na sua conta (não por
        token); senão a primeira conexão whatsapp/waba CONECTADA da sua conta,
        pelo menor id; senão a primeira conexão whatsapp/waba existente, pelo
        menor id (o campo `isDefault` de /v1/connections não entra nessa
        escolha). Envie pelo menos um entre `body`, `medias` (multipart) ou
        `templateData`; fora da janela de 24h do WABA só templates aprovados são
        entregues. `contactName` só é usado se o contato for criado agora. Com
        `saveOnTicket=false` o envio é feito à parte do fluxo normal de
        atendimento (fire-and-forget), mas em conexões WABA o ticket
        criado/reaproveitado é um ticket normal, `status: "open"`, e aparece no
        painel igual a qualquer outra conversa — não é invisível. Nesse modo,
        `medias` é ignorado (só body/templateData chegam ao envio) e o `id` de
        cada mensagem no retorno pode vir `null`. O `status` de cada mensagem no
        retorno pode ser `queued`, `sent`, `server_ack`, `delivered`, `read`,
        `failed`, `received` ou `unknown`. Número ausente devolve 400
        ERR_NUMBER_REQUIRED; número sem dígitos válidos, 400 ERR_NUMBER_INVALID;
        nenhum conteúdo, 400 ERR_MISSING_CONTENT; conexão informada que não
        existe na sua conta, 404 ERR_CONNECTION_NOT_FOUND; nenhuma conexão
        disponível, 404 ERR_NO_CONNECTION_AVAILABLE; conexão de canal diferente
        de whatsapp/waba, 400 ERR_UNSUPPORTED_CHANNEL. Requer escopo
        `messages:send`.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - number
              description: >-
                Pelo menos um entre body, medias (multipart) e templateData é
                obrigatório.
              properties:
                number:
                  type: string
                  example: '5534992341048'
                  description: E.164 sem `+` (DDI+DDD+número).
                body:
                  type: string
                whatsappId:
                  type:
                    - integer
                    - 'null'
                  description: >-
                    Conexão de saída (id). Tem prioridade sobre whatsappName e
                    sobre a conexão padrão.
                whatsappName:
                  type:
                    - string
                    - 'null'
                  description: Conexão de saída pelo nome (alternativa ao id).
                contactName:
                  type:
                    - string
                    - 'null'
                  description: Nome usado se o contato for criado agora.
                templateData:
                  oneOf:
                    - type: object
                      properties:
                        templateName:
                          type: string
                        templateLanguage:
                          type: string
                          example: pt_BR
                        templateParameters:
                          type: array
                          items:
                            type: string
                    - type: string
                    - type: 'null'
                  description: >-
                    Template aprovado do WABA. Aceita um objeto `{ templateName,
                    templateLanguage, templateParameters }` ou, por
                    compatibilidade, a mesma estrutura como string JSON.
                saveOnTicket:
                  type: boolean
                  default: true
                  description: >-
                    false = fire-and-forget: a resposta não traz
                    ticketId/contactId. Em conexões WABA o envio ainda passa por
                    um ticket normal (`status: "open"`), visível no painel;
                    `medias` é ignorado nesse modo.
            examples:
              texto:
                value:
                  number: '5534992341048'
                  body: Olá! Tudo bem?
              template:
                value:
                  number: '5534992341048'
                  templateData:
                    templateName: boleto_atualizado
                    templateLanguage: pt_BR
                    templateParameters:
                      - Maria
                      - R$ 129,90
              templateLegado:
                summary: Aceito por compatibilidade
                value:
                  number: '5534992341048'
                  templateData: >-
                    {"templateName":"boleto_atualizado","templateLanguage":"pt_BR","templateParameters":["Maria","R$
                    129,90"]}
          multipart/form-data:
            schema:
              type: object
              properties:
                number:
                  type: string
                body:
                  type: string
                medias:
                  type: array
                  items:
                    type: string
                    format: binary
      responses:
        '200':
          description: Mensagem aceita; conversa criada/reaproveitada.
          headers:
            X-RateLimit-Limit:
              $ref: '#/components/headers/X-RateLimit-Limit'
            X-RateLimit-Remaining:
              $ref: '#/components/headers/X-RateLimit-Remaining'
            X-RateLimit-Reset:
              $ref: '#/components/headers/X-RateLimit-Reset'
          content:
            application/json:
              schema:
                type: object
                properties:
                  requestId:
                    type: string
                  ticketId:
                    type:
                      - integer
                      - 'null'
                    description: null quando saveOnTicket=false.
                  contactId:
                    type:
                      - integer
                      - 'null'
                  whatsappId:
                    type: integer
                  channel:
                    type: string
                  messages:
                    type: array
                    items:
                      $ref: '#/components/schemas/Message'
              example:
                requestId: req_a10f3e
                ticketId: 4901
                contactId: 602
                whatsappId: 2
                channel: waba
                messages:
                  - id: wamid.HBgN...
                    status: sent
                    ack: 1
                    createdAt: '2026-09-23T09:20:11.000Z'
        '400':
          description: >-
            `ERR_NUMBER_REQUIRED`: O campo `number` é obrigatório. ·
            `ERR_NUMBER_INVALID`: O número não tem dígitos válidos após
            normalização. Use E.164 sem `+` (ex.: 5534999990000). ·
            `ERR_MISSING_CONTENT`: O envio precisa de pelo menos um entre
            `body`, `medias` (multipart) ou `templateData`. ·
            `ERR_UNSUPPORTED_CHANNEL`: A conexão escolhida não é WhatsApp. Só
            canais `whatsapp` e `waba` enviam pela API. Em POST
            /v1/messages/send devolve 400; em POST /v1/flows/trigger, 422.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: ERR_NUMBER_REQUIRED
                code: ERR_NUMBER_REQUIRED
        '401':
          description: >-
            `ERR_TOKEN_MISSING`: Header Authorization ausente. Envie
            `Authorization: Bearer wtx_live_…`. · `ERR_TOKEN_INVALID`: O token
            não existe ou está mal formado. Gere um novo na tela API do Chat →
            Tokens. · `ERR_TOKEN_REVOKED`: O token foi revogado no painel. Crie
            outro. · `ERR_TOKEN_EXPIRED`: Passou da validade definida na
            criação. Crie outro ou rotacione antes de expirar.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: Token não fornecido
                code: ERR_TOKEN_MISSING
        '403':
          description: >-
            `ERR_SCOPE_MISSING`: O token é válido mas não tem o escopo exigido
            pelo endpoint. Um escopo `x:write` satisfaz `x:read`. ·
            `ERR_STORAGE_LIMIT_REACHED`: Limite de armazenamento da instância
            atingido; envio de mídia bloqueado. · `ERR_STORAGE_LIMIT_REACHED`
            vem sem `code`; trate pelo `error`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: Token sem permissão para esta ação
                code: ERR_SCOPE_MISSING
        '404':
          description: >-
            `ERR_CONNECTION_NOT_FOUND`: `whatsappId`/`whatsappName` não
            corresponde a uma conexão desta conta. ·
            `ERR_NO_CONNECTION_AVAILABLE`: A conta não tem conexão padrão ativa.
            Informe `whatsappId` ou configure a conexão padrão no painel.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: Conexão informada não encontrada
                code: ERR_CONNECTION_NOT_FOUND
        '429':
          description: >-
            `ERR_RATE_LIMITED`: Mais de 120 requisições por minuto com o mesmo
            token. Aguarde os segundos de `Retry-After`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: Limite de requisições excedido
                code: ERR_RATE_LIMITED
          headers:
            X-RateLimit-Limit:
              $ref: '#/components/headers/X-RateLimit-Limit'
            X-RateLimit-Remaining:
              $ref: '#/components/headers/X-RateLimit-Remaining'
            X-RateLimit-Reset:
              $ref: '#/components/headers/X-RateLimit-Reset'
            Retry-After:
              $ref: '#/components/headers/Retry-After'
      security:
        - bearerAuth: []
components:
  headers:
    X-RateLimit-Limit:
      schema:
        type: integer
      description: Quantas requisições o token pode fazer por minuto.
    X-RateLimit-Remaining:
      schema:
        type: integer
      description: Quantas requisições ainda restam na janela atual.
    X-RateLimit-Reset:
      schema:
        type: integer
      description: Epoch (segundos) em que a janela de rate limit atual reseta.
    Retry-After:
      schema:
        type: integer
      description: >-
        Só no 429: segundos até poder tentar de novo (igual ao campo
        `retryAfter` do corpo).
  schemas:
    Message:
      type: object
      properties:
        id:
          type: string
          description: ID da mensagem (wamid/uuid).
        ticketId:
          type: integer
        fromMe:
          type: boolean
        body:
          type: string
        mediaUrl:
          type:
            - string
            - 'null'
        mediaType:
          type:
            - string
            - 'null'
          example: image
        ack:
          type: integer
          description: 0-5 (progresso de entrega).
        status:
          type: string
          description: >-
            Legível, derivado do `ack`: queued | sent | server_ack | delivered |
            read | failed | received | unknown. GET
            /v1/messages/{messageId}/status pode devolver ainda `processing`
            enquanto a mensagem não chegou no seu histórico.
        quotedMsgId:
          type:
            - string
            - 'null'
        contactId:
          type:
            - integer
            - 'null'
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
        quotedMsg:
          type:
            - object
            - 'null'
          description: Presente quando a mensagem responde outra.
          properties:
            id:
              type: string
            body:
              type: string
            fromMe:
              type: boolean
            mediaType:
              type:
                - string
                - 'null'
            createdAt:
              type: string
              format: date-time
    Error:
      type: object
      required:
        - error
      additionalProperties: true
      description: >-
        Corpo plano `{ error, code, ...extras }`: extras aparecem na raiz —
        `retryAfter` (429), `requiredScope` (403), `ticketId` (409), `param`
        (filtro de data inválido). Não existe objeto `details`.
      properties:
        error:
          type: string
          description: >-
            Texto do erro (em ~22 códigos é o próprio código). Não faça match
            nele; use `code`.
        code:
          type: string
          enum:
            - ERR_TOKEN_MISSING
            - ERR_TOKEN_INVALID
            - ERR_TOKEN_REVOKED
            - ERR_TOKEN_EXPIRED
            - ERR_SCOPE_MISSING
            - ERR_RATE_LIMITED
            - ERR_MISSING_CONTENT
            - ERR_NUMBER_REQUIRED
            - ERR_NUMBER_INVALID
            - ERR_CONNECTION_NOT_FOUND
            - ERR_NO_CONNECTION_AVAILABLE
            - ERR_UNSUPPORTED_CHANNEL
            - ERR_NO_TICKET_FOUND
            - ERR_MISSING_NUMBER
            - ERR_NUMBER_NOT_ON_WHATSAPP
            - ERR_WHATSAPP_NOT_FOUND
            - ERR_NO_CONTACT_FOUND
            - ERR_NUMBER_IMMUTABLE
            - ERR_INVALID_TAG_IDS
            - ERR_INVALID_TAGMODE
            - ERR_INVALID_DATE_FILTER
            - ERR_NO_CARD_FOUND
            - ERR_CONTACT_IDENTIFIER_REQUIRED
            - ERR_PIPELINE_NOT_FOUND
            - ERR_STAGE_REQUIRED
            - ERR_STAGE_NOT_FOUND
            - ERR_STAGE_NOT_IN_PIPELINE
            - ERR_SOURCE_NOT_FOUND
            - ERR_SOURCE_REQUIRED_FOR_STAGE
            - ERR_FLOW_ID_AND_WHATSAPP_ID_REQUIRED
            - ERR_VARIABLES_MUST_BE_OBJECT
            - ERR_FLOW_NOT_FOUND
            - ERR_FLOW_NOT_EXECUTABLE
            - ERR_TICKET_IN_HUMAN_SERVICE
            - ERR_FEATURE_NOT_AVAILABLE
            - ERR_STORAGE_LIMIT_REACHED
            - ERR_DUPLICATED_CONTACT
            - ERR_CONTACT_NUMBER_IS_LID
          description: Código estável do erro.
        retryAfter:
          type: integer
          description: >-
            Só no 429: segundos até poder tentar de novo (igual ao header
            Retry-After).
        requiredScope:
          type: string
          description: 'Só no 403: escopo que o token não tem.'
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: >-
        Token criado em API → Tokens no painel. Prefixo `wtx_live_` (ou
        `wtx_test_`).

````