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

# Listar modelos

> Lista os modelos que a sua credencial pode consultar, os seus e os pré-aprovados do Pombo.




## OpenAPI

````yaml /api-reference/openapi.yaml get /templates
openapi: 3.1.0
info:
  title: API do Pombo.Digital
  version: 1.0.0
  description: >
    Envie notificações extrajudiciais certificadas por WhatsApp ou e-mail,
    acompanhe a entrega e baixe o laudo com carimbo do tempo ICP-Brasil.


    A credencial identifica a organização por si só: `organization_id` não é
    aceito em nenhuma requisição desta API.
servers:
  - url: https://pombo.digital/api/integrations/v1
    description: Produção
security:
  - bearerAuth: []
tags:
  - name: Notificações
    description: >-
      Criar uma notificação extrajudicial, acompanhar a entrega e baixar o
      laudo.
  - name: Modelos
    description: >-
      Modelos de mensagem. Um envio de WhatsApp exige um modelo aprovado pela
      Meta.
  - name: Saldo
    description: O saldo de envios da organização.
paths:
  /templates:
    get:
      tags:
        - Modelos
      summary: Listar modelos
      description: >
        Lista os modelos que a sua credencial pode consultar, os seus e os
        pré-aprovados do Pombo.
      operationId: listTemplates
      parameters:
        - name: limit
          in: query
          required: false
          description: >
            Quantos modelos trazer, de 1 a 50. O padrão é 10.


            Um valor fora da faixa, ou que não seja um inteiro, é recusado com
            `400` e a mensagem `limit must be an integer from 1 through 50`.
          schema:
            type: integer
            minimum: 1
            maximum: 50
            default: 10
        - name: after
          in: query
          required: false
          description: >
            O cursor da próxima página: copie o `next_cursor` da resposta
            anterior e repita a chamada com ele.


            **É um valor que você recebe, nunca um que você monta.** Precisa ser
            um `template_id`, no formato `PBD_TPL_...`. Um `notification_id` ou
            qualquer outro texto é recusado com `400` e a mensagem `after must
            be a valid template cursor`.
          schema:
            type: string
            pattern: ^PBD_TPL_[0-9A-HJKMNP-TV-Z]{26}$
            examples:
              - PBD_TPL_01J9Z2Q8XK3M7WPTV6RB4CYH0N
        - name: channel
          in: query
          required: false
          description: >
            Traz só os modelos do canal informado.


            **Só em minúsculas**, que é como o canal fica gravado em um modelo.
            `WHATSAPP` é recusado com `400`, assim como qualquer valor fora dos
            dois canais.


            Em `GET /notifications` o mesmo parâmetro aceita qualquer caixa. A
            diferença acompanha o que cada registro guarda.
          schema:
            type: string
            enum:
              - whatsapp
              - email
      responses:
        '200':
          description: Uma página de modelos.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TemplateList'
              examples:
                primeira_pagina:
                  summary: Um modelo seu e um pré-aprovado
                  value:
                    data:
                      - template_id: PBD_TPL_01J9Z2Q8XK3M7WPTV6RB4CYH0N
                        organization_id: PBD_ORG_01J8A1B2C3D4E5F6G7H8J9K0LM
                        name: cobranca_vencida
                        channel: whatsapp
                        body: >-
                          Prezado(a) {{1}}, consta débito de R$ {{2}} com
                          vencimento em {{3}}.
                        template_type: TEXT
                        language_code: pt_BR
                        template_status: APPROVED
                        template_origin: ORG
                        declined_reason: null
                        rejected_reason: null
                        updated_at: '2026-08-27T14:31:52.109Z'
                        variables:
                          '{{1}}':
                            variable_name: nome
                            variable_example: Maria Silva
                          '{{2}}':
                            variable_name: valor
                            variable_example: 1.250,00
                          '{{3}}':
                            variable_name: vencimento
                            variable_example: 10/09/2026
                        created_at: '2026-08-27T14:03:11.482Z'
                      - template_id: PBD_TPL_01J8A1B2C3D4E5F6G7H8J9K0LM
                        organization_id: null
                        name: cobranca_pre_aprovada
                        channel: whatsapp
                        body: Prezado(a) {{1}}, consta débito de R$ {{2}} em aberto.
                        template_type: TEXT
                        language_code: pt_BR
                        template_status: APPROVED
                        template_origin: SYSTEM
                        declined_reason: null
                        rejected_reason: null
                        updated_at: '2026-08-02T09:00:00.000Z'
                        variables:
                          '{{1}}':
                            variable_name: nome
                            variable_example: Maria Silva
                          '{{2}}':
                            variable_name: valor
                            variable_example: 1.250,00
                        created_at: '2026-08-02T09:00:00.000Z'
                    has_more: true
                    next_cursor: PBD_TPL_01J8A1B2C3D4E5F6G7H8J9K0LM
                ultima_pagina:
                  summary: Última página
                  value:
                    data: []
                    has_more: false
                    next_cursor: null
        '400':
          $ref: '#/components/responses/TemplateListBadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'
components:
  schemas:
    TemplateList:
      type: object
      description: >
        Uma página de modelos.


        A paginação é por cursor: não existe número de página e não existe
        total. Para avançar, repita a chamada com `after` igual ao `next_cursor`
        que veio aqui, e pare quando `has_more` for `false`.
      required:
        - data
        - has_more
        - next_cursor
      properties:
        data:
          type: array
          description: >
            Os modelos da página, do mais recente para o mais antigo. Vem vazio
            quando não há nenhum.


            Cada item é o mesmo objeto que a consulta de um modelo devolve. A
            listagem não traz o histórico de alterações.
          items:
            $ref: '#/components/schemas/Template'
        has_more:
          type: boolean
          description: Se existe ao menos mais uma página depois desta.
        next_cursor:
          type:
            - string
            - 'null'
          description: >
            O `template_id` que a próxima chamada deve mandar em `after`. `null`
            quando `has_more` é `false`.


            **Repasse este valor como ele veio.** Ele não é montado pelo
            cliente.
          examples:
            - PBD_TPL_01J9Z2Q8XK3M7WPTV6RB4CYH0N
    Template:
      type: object
      properties:
        template_id:
          type: string
        organization_id:
          type:
            - string
            - 'null'
        name:
          type: string
        channel:
          type: string
          enum:
            - whatsapp
            - email
        body:
          type: string
        body_example:
          type: string
          description: >
            O `body` com cada marcador substituído pelo `variable_example` da
            variável, entre colchetes. Montado pelo Pombo, serve para
            pré-visualizar o texto sem preencher nada.
        template_type:
          type: string
          enum:
            - DOCUMENT
            - IMAGE
            - LOCATION
            - TEXT
            - VIDEO
          description: >
            O tipo de cabeçalho. `DOCUMENT` e `IMAGE` são os que levam arquivo;
            `TEXT` é só texto.


            `VIDEO` e `LOCATION` podem aparecer em modelos antigos e não são
            aceitos ao criar um modelo novo. Um envio com eles não leva arquivo.
        language_code:
          type: string
          enum:
            - pt_BR
            - en_US
            - es_ES
        template_status:
          type: string
          enum:
            - PENDING
            - APPROVED
            - REJECTED
            - PAUSED
            - DISABLED
            - DELETED
            - IN_APPEAL
            - FLAGGED
            - FAILED
          description: >
            Só um modelo `APPROVED` pode ser usado em um envio de WhatsApp. A
            aprovação é da Meta, não do Pombo.


            Um modelo de `whatsapp` nasce `PENDING`: consulte `GET
            /templates/{id}` até chegar a `APPROVED`, e crie os seus modelos com
            antecedência, porque um envio com modelo não aprovado é recusado com
            `422`.


            Um modelo de `email` nasce `APPROVED` e serve para enviar na mesma
            hora.
        template_origin:
          type: string
          enum:
            - SYSTEM
            - ORG
          description: >
            `SYSTEM` são modelos do catálogo do Pombo; `ORG`, os da sua
            organização.


            Na listagem, os seus aparecem em qualquer `template_status`,
            inclusive `PENDING` e `REJECTED`; os do catálogo aparecem só quando
            já estão `APPROVED`. Rascunhos e modelos apagados ficam de fora.
        requires_attachment:
          type:
            - boolean
            - 'null'
          description: >
            Anotação de quem criou o modelo, **sem efeito nenhum**: nada no
            envio a consulta, e enviar sem arquivo não é recusado por causa
            dela. Não a envie.


            Um modelo de `whatsapp` devolve **sempre `null`**, tenha você
            enviado o campo ou não; só um modelo de `email` devolve o valor como
            chegou.


            Para um modelo que leve arquivo, o campo que importa é
            `template_type`, com `DOCUMENT` ou `IMAGE`.
        variables:
          type: object
          additionalProperties:
            $ref: '#/components/schemas/TemplateVariable'
          description: >
            As variáveis do modelo. **Estas chaves são as de `parameters` no
            envio.**


            Os marcadores do rodapé do remetente estão deliberadamente ausentes
            daqui, embora apareçam no `body`: é o Pombo que os preenche, a
            partir do `sender` do envio. Um marcador do `body` sem entrada em
            `variables` é isso, e não um erro.
        subject:
          type:
            - string
            - 'null'
          description: >
            Campo histórico, **sem efeito**: não é o assunto que o destinatário
            recebe. O assunto de um e-mail é montado no momento do envio a
            partir do nome da organização.


            **Sempre `null` em um modelo criado pela API**, nos dois canais: o
            campo não é gravado na criação. Só traz conteúdo em modelos antigos.
        declined_reason:
          type:
            - string
            - 'null'
          enum:
            - ABUSIVE_CONTENT
            - SCAM
            - INVALID_FORMAT
            - TAG_CONTENT_MISMATCH
            - INCORRECT_CATEGORY
            - REVIEW_TIMEOUT
            - UNKNOWN
            - null
          description: >
            Por que a Meta recusou o modelo, quando `template_status` é
            `REJECTED` ou `FAILED`. `null` enquanto não houve recusa.


            `ABUSIVE_CONTENT` e `SCAM` exigem reescrever o texto.
            `INVALID_FORMAT`, `TAG_CONTENT_MISMATCH` e `INCORRECT_CATEGORY` são
            erros de forma. `REVIEW_TIMEOUT` é falha da própria revisão e um
            modelo novo com o mesmo texto pode passar.
        rejected_reason:
          type:
            - string
            - 'null'
          description: >
            O motivo em texto livre, como o provedor o enviou. **Não é estável e
            não deve ser comparado em código:** para ramificar, use
            `declined_reason`.
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
          description: >
            A última alteração do registro. **Muda sem você fazer nada:** a Meta
            atualiza o status e a categoria por webhook, e cada atualização mexe
            neste campo.
    Error:
      type: object
      description: >
        O envelope de erro, com quatro campos.


        **Ramifique pelo status HTTP e por `error_code`. Nunca por `code`.** O
        `code` vale `10000 + http_code` em um caminho e uma string arbitrária em
        outro, então não acrescenta nada ao status e muda de tipo entre
        operações vizinhas.
      required:
        - message
      properties:
        code:
          description: >
            **Não ramifique por este campo.** O tipo muda entre operações
            vizinhas: um `404` de modelo traz `10404` e um `404` de notificação
            traz `"NOT_FOUND"`. Para tratar erros em código, use o status HTTP.
          oneOf:
            - title: Número, na validação genérica
              type: integer
              description: >-
                `10000 + http_code`. Um `400` genérico traz `10400`, um `404`
                traz `10404`.
              examples:
                - 10400
            - title: Texto, nos erros específicos
              type: string
              description: Um identificador do erro, como os listados em Erros.
              examples:
                - IDEMPOTENCY_KEY_REUSED
        http_code:
          type: integer
          description: >
            **Opcional.** O status HTTP repetido no corpo. Presente quando o
            erro é devolvido diretamente, ausente quando é lançado e tratado
            pelo tratador geral. Nunca exija este campo no cliente.
        message:
          type: string
          description: >-
            Descrição da falha, para diagnóstico. Em inglês ou em português. Não
            é estável.
        error_code:
          type: string
          enum:
            - MISSING_REQUIRED_FIELD
            - INVALID_SENDER
            - ORGANIZATION_ID_FORBIDDEN
            - INVALID_RECIPIENT
            - TEMPLATE_CONSTANT_FORBIDDEN
            - FILE_TRANSFER_NOT_AVAILABLE_ON_THIS_LANE
            - IDEMPOTENCY_KEY_REUSED
          description: >
            O campo a usar para ramificar. **Opcional na prática:** alguns `400`
            igualmente específicos não o trazem, como o de
            `recipient_tax_id_type` fora do enum e o de `Idempotency-Key` mal
            formado. Quando estiver ausente, use o status HTTP.
    InternalError:
      type: object
      description: O corpo do `500` é reduzido e **não** traz `http_code`.
      properties:
        code:
          type: string
          examples:
            - INTERNAL_ERROR
        message:
          type: string
          examples:
            - Internal Server Error
        request_id:
          type: string
          description: >
            O mesmo valor do cabeçalho `x-request-id`. **Registre-o:** é por ele
            que o suporte encontra a requisição exata.
          examples:
            - req_01M1C5ZKGBGRNW6QHXTP2EM7Y7
    TemplateVariable:
      type: object
      required:
        - variable_name
        - variable_example
      properties:
        variable_name:
          type: string
          description: Um rótulo seu, para se orientar. Não é a chave.
          examples:
            - nome
        variable_example:
          type: string
          description: >
            Um valor de exemplo. Em `whatsapp` a Meta o usa para aprovar o
            modelo.


            **Em `email` a marcação é removida antes de armazenar**, então um
            exemplo com HTML volta sem ele em `GET /templates/{id}`.
          examples:
            - Maria Silva
  responses:
    TemplateListBadRequest:
      description: >
        Parâmetro de consulta inválido. Repetir sem alterar nada devolve o mesmo
        erro.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          examples:
            parametro_nao_aceito:
              summary: 'Sem error_code: parâmetro fora dos três aceitos'
              description: >
                A listagem aceita `limit`, `after` e `channel`, e recusa
                qualquer outro nome. `all`, `search`, `page` e `type` caem aqui.
              value:
                code: 10400
                http_code: 400
                message: 'Invalid request: Unsupported query parameter: search'
            limite_invalido:
              summary: 'Sem error_code: limit fora da faixa'
              value:
                code: 10400
                http_code: 400
                message: 'Invalid request: limit must be an integer from 1 through 50'
            cursor_invalido:
              summary: 'Sem error_code: after que não é um template_id'
              description: >
                O cursor desta listagem é um `PBD_TPL_...`. O cursor de `GET
                /notifications` é recusado aqui.
              value:
                code: 10400
                http_code: 400
                message: 'Invalid request: after must be a valid template cursor'
            canal_invalido:
              summary: 'Sem error_code: channel fora dos dois canais, ou em maiúsculas'
              value:
                code: 10400
                http_code: 400
                message: 'Invalid request: channel must be either whatsapp or email'
            organization_id_proibido:
              summary: organization_id enviado na consulta
              value:
                code: 10400
                http_code: 400
                message: >-
                  Invalid request: organization_id must not be sent as a query
                  parameter: it is taken from the API key
                error_code: ORGANIZATION_ID_FORBIDDEN
    Unauthorized:
      description: >
        Credencial ausente, inválida ou revogada. A resposta é **idêntica** nos
        três casos: o Pombo não informa qual deles ocorreu, para que não se
        possa descobrir por tentativa quais credenciais já existiram.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          examples:
            invalida:
              summary: Credencial não aceita
              value:
                code: 10401
                http_code: 401
                message: Invalid API key
    TooManyRequests:
      description: >
        Limite de requisições excedido. São três contagens independentes, em
        janelas de um minuto: 50 por credencial, 200 por organização, 300 por
        IP.


        **Espere o que o `Retry-After` manda esperar**, em segundos. Os
        cabeçalhos `RateLimit-Limit`, `RateLimit-Remaining` e `RateLimit-Reset`
        vêm em toda resposta, não só no `429`.
      headers:
        Retry-After:
          description: Quantos segundos esperar antes de repetir.
          schema:
            type: integer
            examples:
              - 43
        RateLimit-Limit:
          description: O teto da janela.
          schema:
            type: integer
            examples:
              - 200
        RateLimit-Remaining:
          description: Quantas requisições ainda cabem na janela.
          schema:
            type: integer
            examples:
              - 0
        RateLimit-Reset:
          description: Quantos segundos faltam para a janela virar.
          schema:
            type: integer
            examples:
              - 43
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          examples:
            limite:
              summary: Limite excedido
              value:
                code: RATE_LIMIT_EXCEEDED
                http_code: 429
                message: Too many requests. Please try again later.
    InternalError:
      description: >
        Erro interno. Em `POST /notifications`, um `500` **não garante que nada
        foi enviado**: consulte antes de repetir.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/InternalError'
          examples:
            interno:
              summary: Erro interno
              value:
                code: INTERNAL_ERROR
                message: Internal Server Error
                request_id: req_01M1C5ZKGBGRNW6QHXTP2EM7Y7
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: >
        Sua credencial de API no cabeçalho `Authorization: Bearer sk_live_...`.
        Crie e revogue credenciais no painel, em Conta → API Keys. O segredo
        aparece uma única vez, na criação.


        A credencial identifica a organização: `organization_id` não é aceito em
        nenhuma requisição.

````