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

# Consulta um modelo.

> Devolve um modelo pelo `template_id`.

**Chame antes de cada envio.** As chaves de `variables` são as que `parameters` precisa preencher em `POST /notifications`, e é aqui que você confere o `template_status`.

Não acrescente `?organization_id=`: a credencial já diz a organização, e o parâmetro é recusado com `400 ORGANIZATION_ID_FORBIDDEN`.




## OpenAPI

````yaml /api-reference/openapi.yaml get /templates/{id}
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.
paths:
  /templates/{id}:
    get:
      tags:
        - Modelos
      summary: Consulta um modelo.
      description: >
        Devolve um modelo pelo `template_id`.


        **Chame antes de cada envio.** As chaves de `variables` são as que
        `parameters` precisa preencher em `POST /notifications`, e é aqui que
        você confere o `template_status`.


        Não acrescente `?organization_id=`: a credencial já diz a organização, e
        o parâmetro é recusado com `400 ORGANIZATION_ID_FORBIDDEN`.
      operationId: getTemplate
      parameters:
        - $ref: '#/components/parameters/TemplateId'
      responses:
        '200':
          description: O modelo.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Template'
              examples:
                aprovado:
                  summary: Aprovado, pronto para uso
                  value:
                    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'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'
components:
  parameters:
    TemplateId:
      name: id
      in: path
      required: true
      description: O identificador do modelo.
      schema:
        type: string
        pattern: ^PBD_TPL_[0-9A-HJKMNP-TV-Z]{26}$
        examples:
          - PBD_TPL_01J9Z2Q8XK3M7WPTV6RB4CYH0N
  schemas:
    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.
        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.**
        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.
    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
    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
  responses:
    BadRequest:
      description: Requisição inválida. Repetir sem alterar nada devolve o mesmo erro.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          examples:
            json_malformado:
              summary: 'Sem error_code: corpo JSON mal formado'
              value:
                code: 10400
                http_code: 400
                message: 'Invalid request: malformed JSON'
            canal_invalido:
              summary: 'Sem error_code: channel fora dos dois canais aceitos'
              value:
                code: 10400
                http_code: 400
                message: 'Invalid request: channel must be WHATSAPP or EMAIL'
            campo_faltando:
              summary: Campo obrigatório faltando
              value:
                code: 10400
                http_code: 400
                message: 'Invalid request: Missing required fields: template_id'
                error_code: MISSING_REQUIRED_FIELD
            organization_id_proibido:
              summary: organization_id enviado
              value:
                code: 10400
                http_code: 400
                message: >-
                  Invalid request: organization_id is not accepted on this
                  endpoint: the API key decides the organization
                error_code: ORGANIZATION_ID_FORBIDDEN
            anexo_por_id:
              summary: 'Sem error_code: attachment_id enviado no envio'
              description: >
                O primeiro erro de quem vem do fluxo antigo de duas chamadas.
                Nesta API o arquivo viaja na própria requisição, como a parte
                `file` de um `multipart/form-data`.
              value:
                code: 10400
                http_code: 400
                message: >-
                  Invalid request: attachment_id is not available on the
                  integrations lane; use multipart/form-data with a file part
            transferencia_de_arquivo:
              summary: file_transfer_id enviado no envio
              value:
                code: 10400
                http_code: 400
                message: >-
                  Invalid request: file_transfer_id is not available on the
                  integrations lane
                error_code: FILE_TRANSFER_NOT_AVAILABLE_ON_THIS_LANE
            constante_de_modelo:
              summary: language_code ou template_category_type em POST /templates
              value:
                code: 10400
                http_code: 400
                message: >-
                  Invalid request: language_code must not be sent: it is set by
                  the server
                error_code: TEMPLATE_CONSTANT_FORBIDDEN
            remetente_invalido:
              summary: sender ausente ou não é objeto
              value:
                code: 10400
                http_code: 400
                message: 'Invalid request: sender is required and must be an object'
                error_code: INVALID_SENDER
            destinatario_invalido:
              summary: Campo de contato do canal ausente
              value:
                code: 10400
                http_code: 400
                message: 'Invalid request: recipient_phone is required for this channel'
                error_code: INVALID_RECIPIENT
            telefone_invalido:
              summary: Telefone fora do formato
              value:
                code: 10400
                http_code: 400
                message: >-
                  Invalid request: recipient_phone must start with '+' (e.g.,
                  +5511999998888)
            tipo_de_documento_invalido:
              summary: 'Sem error_code: tipo de documento fora do enum'
              value:
                code: 10400
                http_code: 400
                message: 'Invalid request: recipient_tax_id_type must be CPF or CNPJ'
            chave_de_idempotencia_invalida:
              summary: 'Sem error_code: Idempotency-Key mal formada'
              value:
                code: 10400
                http_code: 400
                message: >-
                  Invalid request: Idempotency-Key may only contain letters,
                  digits, underscores and hyphens
            arquivo_grande_demais:
              summary: 'Sem error_code: anexo acima do limite'
              description: >
                O anexo grande demais é `400`, **não `413`**. Os limites vêm do
                tipo do arquivo: 20 MB para PDF, 5 MB para imagem.
              value:
                code: 10400
                http_code: 400
                message: 'Invalid request: File size exceeds maximum allowed (20MB)'
            partes_fora_de_ordem:
              summary: 'Sem error_code: parte notification ausente ou depois do arquivo'
              description: >
                A parte `notification` é validada enquanto o arquivo ainda sobe,
                então precisa vir **antes** da parte `file`.
              value:
                code: 10400
                http_code: 400
                message: >-
                  Invalid request: The notification part is required and must
                  come before the file part
            partes_demais:
              summary: 'Sem error_code: uma terceira parte no multipart'
              value:
                code: 10400
                http_code: 400
                message: >-
                  Invalid request: multipart/form-data accepts exactly one
                  notification part and one file part
            variaveis_invalidas:
              summary: Variáveis não correspondem ao modelo
              value:
                code: INVALID_PARAMETERS
                http_code: 400
                message: 'Missing required parameter: {{1}}'
    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
    NotFound:
      description: >
        Recurso não encontrado. Um recurso de **outra organização** também
        responde `404`, e não `403`, porque a distinção revelaria que o
        identificador existe. Vale para os dois `GET` e também para o
        `template_id` de um envio.


        O `404` de modelo em `POST /notifications` é devolvido direto pela rota,
        então **não traz `request_id` no corpo**, ao contrário dos erros que
        passam pelo tratador geral. O cabeçalho `x-request-id` está sempre lá:
        use o cabeçalho.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          examples:
            numerico:
              summary: Código numérico
              value:
                code: 10404
                http_code: 404
                message: Template not found
            texto:
              summary: Código em texto
              value:
                code: NOT_FOUND
                http_code: 404
                message: Notification not found
    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.

````