> ## 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.

# Consultar card por ID

> Consulta um card específico pelo id, com o mesmo formato devolvido em GET /v1/cards (pipeline, etapa, contato com suas tags, responsável, origem e motivo de perda quando aplicável). Útil pra conferir o estado atual de um card antes de mover a etapa com PATCH /v1/cards/{cardId}/stage. Card inexistente ou de outra conta devolve 404 ERR_NO_CARD_FOUND, sem distinguir os dois casos. Requer escopo `cards:read`.



## OpenAPI

````yaml /openapi/wapi-v1.pt.json get /v1/cards/{cardId}
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/cards/{cardId}:
    get:
      tags:
        - Cards
      summary: Consultar card por ID
      description: >-
        Consulta um card específico pelo id, com o mesmo formato devolvido em
        GET /v1/cards (pipeline, etapa, contato com suas tags, responsável,
        origem e motivo de perda quando aplicável). Útil pra conferir o estado
        atual de um card antes de mover a etapa com PATCH
        /v1/cards/{cardId}/stage. Card inexistente ou de outra conta devolve 404
        ERR_NO_CARD_FOUND, sem distinguir os dois casos. Requer escopo
        `cards:read`.
      parameters:
        - name: cardId
          in: path
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: Card encontrado.
          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
                  card:
                    $ref: '#/components/schemas/Card'
              example:
                requestId: req_a3f001
                card:
                  id: 981
                  title: API — Maria Souza
                  value: 1500
                  status: open
                  probability: 50
                  pipeline:
                    id: 2
                    name: Vendas
                  stage:
                    id: 8
                    name: Qualificação
                  contact:
                    id: 601
                    name: Maria Souza
                    number: '5534992341048'
                    email: null
                    tags:
                      - id: 3
                        name: Cliente ativo
                  user:
                    id: 12
                    name: Ana Paula
                  source:
                    id: 4
                    name: Indicação
                  lostReason: null
                  originTicketId: null
                  expectedCloseDate: '2026-10-15'
                  closedAt: null
                  stageEnteredAt: '2026-09-20T13:00:00.000Z'
                  createdAt: '2026-09-20T13:00:00.000Z'
                  updatedAt: '2026-09-20T13:00:00.000Z'
        '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_FEATURE_NOT_AVAILABLE`: Recurso não incluído no seu plano
            (middleware hasFeature). · `ERR_FEATURE_NOT_AVAILABLE` 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_NO_CARD_FOUND`: Card inexistente ou de outra conta.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: ERR_NO_CARD_FOUND
                code: ERR_NO_CARD_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:
    Card:
      type: object
      properties:
        id:
          type: integer
        title:
          type: string
        value:
          type:
            - number
            - 'null'
        status:
          type: string
          example: open
          description: open | won | lost
        probability:
          type:
            - integer
            - 'null'
          example: 50
        pipeline:
          type:
            - object
            - 'null'
          properties:
            id:
              type: integer
            name:
              type: string
        stage:
          type:
            - object
            - 'null'
          properties:
            id:
              type: integer
            name:
              type: string
        contact:
          type:
            - object
            - 'null'
          properties:
            id:
              type: integer
            name:
              type: string
            number:
              type: string
            email:
              type:
                - string
                - 'null'
            tags:
              type: array
              items:
                $ref: '#/components/schemas/Tag'
        user:
          type:
            - object
            - 'null'
          properties:
            id:
              type: integer
            name:
              type: string
        source:
          type:
            - object
            - 'null'
          properties:
            id:
              type: integer
            name:
              type: string
        lostReason:
          type:
            - object
            - 'null'
          properties:
            id:
              type: integer
            name:
              type: string
        originTicketId:
          type:
            - integer
            - 'null'
        expectedCloseDate:
          type:
            - string
            - 'null'
          format: date
          description: >-
            Data de calendário (YYYY-MM-DD). ISO completo é aceito na entrada e
            reduzido ao dia em UTC.
        closedAt:
          type:
            - string
            - 'null'
          format: date-time
        stageEnteredAt:
          type:
            - string
            - 'null'
          format: date-time
        createdAt:
          type: string
          format: date-time
        updatedAt:
          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.'
    Tag:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string
        color:
          type: string
          example: '#3B82F6'
        kanban:
          type:
            - integer
            - 'null'
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: >-
        Token criado em API → Tokens no painel. Prefixo `wtx_live_` (ou
        `wtx_test_`).

````