{
  "info": {
    "_postman_id": "c503fb90-0481-5d90-a721-fbd6d24b27c7",
    "name": "Joinotify API",
    "version": "2.1.0",
    "description": "A **Joinotify Cloud** é uma provedora de tecnologia homologada pela Meta que dá\nacesso à API oficial do WhatsApp (Meta Cloud API) através da nossa infraestrutura\n— sem Business Manager verificada, sem App Review e sem configurar nada nos\npainéis da Meta.\n\nConecte um número em [app.joinotify.com](https://app.joinotify.com) e você recebe\num token no formato `sk_live_xxx`, pronto para usar.\n\n## Duas superfícies, um token\n\n**API simplificada** — um endpoint por tipo de mensagem, com o payload reduzido ao\nessencial. O número de origem sai do próprio token.\n\n**API espelhada (`/v1`)** — o contrato da Meta Cloud API byte a byte. Se você já\ntem código escrito contra o Graph, troque o domínio e o token:\n\n| De | Para |\n|---|---|\n| `https://graph.facebook.com/v21.0/` | `https://api.joinotify.com/v1/` |\n| `Bearer <META_TOKEN>` | `Bearer sk_live_xxx` |\n\nSeu token do Joinotify substitui completamente o token da Meta — a credencial\nreal nunca é exposta.\n\n## Token sempre no header\n\nA documentação da Meta mostra exemplos com `?access_token=` na URL. **No Joinotify\nisso não funciona.** O token deve ser enviado sempre no header\n`Authorization: Bearer sk_live_xxx`.\n\n## Limites de uso\n\n| Categoria | Rotas | Limite |\n|---|---|---|\n| Envio de mensagens | `POST /messages` e `POST /v1/.../messages` | 500 req/min |\n| Upload de mídia | `POST /v1/.../media` | 60 req/min |\n| Consultas | todo o resto | 60 req/min |\n\nAo estourar, a API responde `429` com `Retry-After` indicando quantos segundos\naguardar.\n\n## Códigos que valem para toda a API\n\n- **`402`** — sem direito de uso. O corpo traz `reason`: `past_due`,\n  `license_expired`, `trial_ended`, `message_limit`, `canceled`.\n  `/account` e `/billing` nunca respondem `402`: é onde a cobrança se resolve.\n- **`405`** — o caminho existe, mas não com esse método. O header `Allow` diz\n  quais servem.\n\n## Paginação\n\nToda listagem aceita `?limit=` e `?offset=` e responde\n`{ data, total, limit, offset }`. O `total` é a contagem **sem** o recorte de\npágina — é com ele que se sabe quando parou de haver próxima.\n\n## Endpoints bloqueados\n\nPor segurança, o espelho recusa com `403` qualquer caminho que contenha\n`subscribed_apps`, `register`, `deregister`, `request_code`, `verify_code`,\n`assigned_users`, `system_users`, `debug_token`, `oauth` ou `uploads`, além de\n`POST` direto no ID de um número.\n\n## Como usar esta collection\n\n1. Importe também o ambiente `Joinotify.postman_environment.json` (ou crie um com `baseUrl` e `apiKey`) e preencha `apiKey` com uma `sk_live_...` gerada no painel.\n2. Rode `GET /account/senders` primeiro: ele guarda `phoneNumberId` e `wabaId` do seu primeiro número, que o espelho (`/v1`) e várias rotas usam. Para as bases de clientes, preencha `businessId`.\n3. Os ids (`contactId`, `broadcastId`, `flowId`...) se preenchem sozinhos: criar um recurso, ou listar quando a variável está vazia, guarda o id para as chamadas seguintes.\n4. Uploads em bytes crus (mídia de campanha e da inbox) usam `mediaContentType` como `Content-Type` — ajuste para o tipo do arquivo escolhido.\n\n_Gerada a partir da referência da API (v2.1.0) publicada em https://docs.joinotify.com._",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
  },
  "auth": {
    "type": "bearer",
    "bearer": [
      {
        "key": "token",
        "value": "{{apiKey}}",
        "type": "string"
      }
    ]
  },
  "item": [
    {
      "id": "1e3920cf-31b8-5bb2-a622-28cc462f6ba4",
      "name": "Conta",
      "description": "Dados da conta associada ao token, números de origem, consumo e desconexão de\ncontas do WhatsApp.\n\nSe você ainda não sabe seu `phone_number_id` ou `waba_id`, comece por\n`GET /me` — todos os endpoints do espelho `/v1` pedem esses identificadores.",
      "item": [
        {
          "id": "f71d11fc-4780-598f-a8eb-a95112162b96",
          "name": "Dados da conta",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/account/me",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "account",
                "me"
              ]
            },
            "description": "Sua conta, com as contas do WhatsApp (WABAs) e os números de cada uma.\n\nCom uma chave restrita a números específicos, só aparecem a WABA e os números que\nela alcança."
          },
          "response": []
        },
        {
          "id": "b4028a7a-9669-5fd6-ad8f-ccaadce4f515",
          "name": "Listar números de origem",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "if (pm.response.code === 200) {",
                  "  const json = pm.response.json();",
                  "  const first = json && Array.isArray(json.data) && json.data[0];",
                  "  if (first && !pm.collectionVariables.get('phoneNumberId')) pm.collectionVariables.set('phoneNumberId', first.phoneNumberId);",
                  "  if (first && !pm.collectionVariables.get('wabaId')) pm.collectionVariables.set('wabaId', first.wabaId);",
                  "}"
                ]
              }
            }
          ],
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/account/senders",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "account",
                "senders"
              ]
            },
            "description": "Rode primeiro: guarda `phoneNumberId` e `wabaId` do primeiro número (quando ainda estão vazios), que o espelho `/v1` e outras rotas usam.\n\nOs números prontos para usar como origem, achatados numa lista só — é o que uma\nintegração itera na tela de configuração.\n\nVem do nosso espelho local, não da Meta: não gasta chamada nem cota de consulta."
          },
          "response": []
        },
        {
          "id": "48a46590-f4da-56bf-a0e6-dfa8ff11ea3c",
          "name": "Consumo da conta",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/account/usage",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "account",
                "usage"
              ],
              "query": [
                {
                  "key": "period",
                  "value": "2026-08",
                  "disabled": true,
                  "description": "Período no formato `YYYY-MM`. Ausente, traz todos."
                }
              ]
            },
            "description": "Requisições e mensagens contabilizadas por número e por período (`YYYY-MM`), com\nos totais."
          },
          "response": []
        },
        {
          "id": "0b0de38f-2eb2-5d63-a448-9fca88f6cc27",
          "name": "Desconectar uma conta do WhatsApp",
          "request": {
            "method": "DELETE",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/account/wabas/:wabaId",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "account",
                "wabas",
                ":wabaId"
              ],
              "variable": [
                {
                  "key": "wabaId",
                  "value": "{{wabaId}}"
                }
              ]
            },
            "description": "Sai do caminho: desassinamos os webhooks e apagamos o que só existia aqui (token,\nnúmeros, espelho de templates).\n\n**Não** desregistramos o número na Meta — a conta continua sendo sua, e um\n`/deregister` quebraria o número para qualquer provedor."
          },
          "response": []
        }
      ]
    },
    {
      "id": "799e84de-10ce-526a-a960-87a08b8d0f39",
      "name": "Mensagens",
      "description": "Envio de mensagens no formato simplificado. O número de origem é resolvido a\npartir do token, então você não precisa montar o payload completo da Meta.\n\nInforme `from` apenas quando a conta tiver mais de um número conectado e você\nquiser escolher qual usa.\n\n## A janela de 24 horas\n\nO WhatsApp só permite mensagem de conteúdo livre dentro de **24 horas** contadas\na partir da última mensagem enviada pelo cliente. Fora dessa janela, apenas\ntemplates aprovados são aceitos — qualquer outro envio volta com\n`422 meta_error` e o código `131047` da Meta.\n\n## Respondendo uma mensagem\n\nTodos os endpoints de envio aceitam `contextMessageId`. Preencha com o `wamid`\nde uma mensagem recebida para que a sua resposta apareça citando ela no\naplicativo do cliente.",
      "item": [
        {
          "id": "3e7016ab-540a-5a0b-aeb6-c0bfa7a25251",
          "name": "Enviar texto",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}",
                "disabled": true,
                "description": "Identificador da operação, escolhido por você — de 8 a 128 caracteres entre letras,\ndígitos, `_`, `-`, `.` e `:`. Repetir a chamada com o mesmo valor e o mesmo corpo\ndevolve a primeira resposta em vez de executar de novo. Vale por 24 horas, por conta."
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"type\": \"text\",\n  \"to\": \"5541987111527\",\n  \"body\": \"Olá! Seu pedido foi confirmado.\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/messages",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "messages"
              ]
            },
            "description": "Texto livre — só entrega dentro da janela de 24 h desde a última mensagem do contato.\n\nÚnico caminho de envio. O que muda entre um texto e um template é o `type` no\ncorpo — não a URL.\n\n| `type` | Para quê |\n|---|---|\n| `text` | Texto livre. Só dentro da janela de 24 h |\n| `template` | Template aprovado. Abre conversa a qualquer momento |\n| `test` | Igual a `template`, com o `hello_world` como padrão e erros traduzidos |\n\nPrecisa de imagem, vídeo, documento, botões ou carrossel? O caminho é o espelho:\n`POST /v1/{phone_number_id}/messages` aceita o payload da Cloud API inteiro, com\nqualquer tipo que a Meta suporte.\n\n**Agendamento.** Com `sendAt` (instante ISO 8601) ou `delaySeconds` (relativo), a\nresposta é `202` e a mensagem entra na fila. Direito de uso e número são\nreconferidos **na hora de enviar**, não agora.\n\n**Idempotência.** Com o header `Idempotency-Key`, uma repetição da mesma chamada\ndevolve a primeira resposta, com `Idempotent-Replayed: true`, e nada é enviado de\nnovo — nem quando a primeira resposta foi um erro. A mesma chave com outro corpo é\nrecusada com `422 idempotency_key_reused`; enquanto a primeira requisição ainda roda,\na repetição recebe `409 idempotency_in_progress`."
          },
          "response": []
        },
        {
          "id": "f9433c24-8f8e-5185-ae55-c4ed75a42441",
          "name": "Enviar template",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}",
                "disabled": true,
                "description": "Identificador da operação, escolhido por você — de 8 a 128 caracteres entre letras,\ndígitos, `_`, `-`, `.` e `:`. Repetir a chamada com o mesmo valor e o mesmo corpo\ndevolve a primeira resposta em vez de executar de novo. Vale por 24 horas, por conta."
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"type\": \"template\",\n  \"to\": \"5541987111527\",\n  \"name\": \"confirmacao_pedido\",\n  \"language\": \"pt_BR\",\n  \"components\": [\n    {\n      \"type\": \"body\",\n      \"parameters\": [\n        {\n          \"type\": \"text\",\n          \"text\": \"Maria\"\n        },\n        {\n          \"type\": \"text\",\n          \"text\": \"1042\"\n        }\n      ]\n    }\n  ]\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/messages",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "messages"
              ]
            },
            "description": "Template aprovado: abre conversa a qualquer momento.\n\nÚnico caminho de envio. O que muda entre um texto e um template é o `type` no\ncorpo — não a URL.\n\n| `type` | Para quê |\n|---|---|\n| `text` | Texto livre. Só dentro da janela de 24 h |\n| `template` | Template aprovado. Abre conversa a qualquer momento |\n| `test` | Igual a `template`, com o `hello_world` como padrão e erros traduzidos |\n\nPrecisa de imagem, vídeo, documento, botões ou carrossel? O caminho é o espelho:\n`POST /v1/{phone_number_id}/messages` aceita o payload da Cloud API inteiro, com\nqualquer tipo que a Meta suporte.\n\n**Agendamento.** Com `sendAt` (instante ISO 8601) ou `delaySeconds` (relativo), a\nresposta é `202` e a mensagem entra na fila. Direito de uso e número são\nreconferidos **na hora de enviar**, não agora.\n\n**Idempotência.** Com o header `Idempotency-Key`, uma repetição da mesma chamada\ndevolve a primeira resposta, com `Idempotent-Replayed: true`, e nada é enviado de\nnovo — nem quando a primeira resposta foi um erro. A mesma chave com outro corpo é\nrecusada com `422 idempotency_key_reused`; enquanto a primeira requisição ainda roda,\na repetição recebe `409 idempotency_in_progress`."
          },
          "response": []
        },
        {
          "id": "4375c223-140a-5e11-a882-e9328e7f9477",
          "name": "Agendar template",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}",
                "disabled": true,
                "description": "Identificador da operação, escolhido por você — de 8 a 128 caracteres entre letras,\ndígitos, `_`, `-`, `.` e `:`. Repetir a chamada com o mesmo valor e o mesmo corpo\ndevolve a primeira resposta em vez de executar de novo. Vale por 24 horas, por conta."
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"type\": \"template\",\n  \"to\": \"5541987111527\",\n  \"name\": \"confirmacao_pedido\",\n  \"language\": \"pt_BR\",\n  \"delaySeconds\": 300,\n  \"components\": [\n    {\n      \"type\": \"body\",\n      \"parameters\": [\n        {\n          \"type\": \"text\",\n          \"text\": \"Maria\"\n        },\n        {\n          \"type\": \"text\",\n          \"text\": \"1042\"\n        }\n      ]\n    }\n  ]\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/messages",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "messages"
              ]
            },
            "description": "Com `delaySeconds` (ou `sendAt`, um instante ISO 8601) a resposta é `202` e a mensagem entra na fila.\n\nÚnico caminho de envio. O que muda entre um texto e um template é o `type` no\ncorpo — não a URL.\n\n| `type` | Para quê |\n|---|---|\n| `text` | Texto livre. Só dentro da janela de 24 h |\n| `template` | Template aprovado. Abre conversa a qualquer momento |\n| `test` | Igual a `template`, com o `hello_world` como padrão e erros traduzidos |\n\nPrecisa de imagem, vídeo, documento, botões ou carrossel? O caminho é o espelho:\n`POST /v1/{phone_number_id}/messages` aceita o payload da Cloud API inteiro, com\nqualquer tipo que a Meta suporte.\n\n**Agendamento.** Com `sendAt` (instante ISO 8601) ou `delaySeconds` (relativo), a\nresposta é `202` e a mensagem entra na fila. Direito de uso e número são\nreconferidos **na hora de enviar**, não agora.\n\n**Idempotência.** Com o header `Idempotency-Key`, uma repetição da mesma chamada\ndevolve a primeira resposta, com `Idempotent-Replayed: true`, e nada é enviado de\nnovo — nem quando a primeira resposta foi um erro. A mesma chave com outro corpo é\nrecusada com `422 idempotency_key_reused`; enquanto a primeira requisição ainda roda,\na repetição recebe `409 idempotency_in_progress`."
          },
          "response": []
        },
        {
          "id": "bba61708-5ae6-53bc-aecd-5f5a05097a57",
          "name": "Enviar mensagem de teste",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}",
                "disabled": true,
                "description": "Identificador da operação, escolhido por você — de 8 a 128 caracteres entre letras,\ndígitos, `_`, `-`, `.` e `:`. Repetir a chamada com o mesmo valor e o mesmo corpo\ndevolve a primeira resposta em vez de executar de novo. Vale por 24 horas, por conta."
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"type\": \"test\",\n  \"to\": \"5541987111527\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/messages",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "messages"
              ]
            },
            "description": "O `hello_world` por padrão — a Meta só o entrega em números de teste; em produção informe `name` de um template seu.\n\nÚnico caminho de envio. O que muda entre um texto e um template é o `type` no\ncorpo — não a URL.\n\n| `type` | Para quê |\n|---|---|\n| `text` | Texto livre. Só dentro da janela de 24 h |\n| `template` | Template aprovado. Abre conversa a qualquer momento |\n| `test` | Igual a `template`, com o `hello_world` como padrão e erros traduzidos |\n\nPrecisa de imagem, vídeo, documento, botões ou carrossel? O caminho é o espelho:\n`POST /v1/{phone_number_id}/messages` aceita o payload da Cloud API inteiro, com\nqualquer tipo que a Meta suporte.\n\n**Agendamento.** Com `sendAt` (instante ISO 8601) ou `delaySeconds` (relativo), a\nresposta é `202` e a mensagem entra na fila. Direito de uso e número são\nreconferidos **na hora de enviar**, não agora.\n\n**Idempotência.** Com o header `Idempotency-Key`, uma repetição da mesma chamada\ndevolve a primeira resposta, com `Idempotent-Replayed: true`, e nada é enviado de\nnovo — nem quando a primeira resposta foi um erro. A mesma chave com outro corpo é\nrecusada com `422 idempotency_key_reused`; enquanto a primeira requisição ainda roda,\na repetição recebe `409 idempotency_in_progress`."
          },
          "response": []
        },
        {
          "id": "ffc2b807-e82f-552d-ad87-e4dca967186d",
          "name": "Listar agendamentos",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "if (pm.response.code === 200 && !pm.collectionVariables.get('scheduledMessageId')) {",
                  "  const json = pm.response.json();",
                  "  const first = json && Array.isArray(json.data) && json.data[0];",
                  "  if (first && first.id) pm.collectionVariables.set('scheduledMessageId', first.id);",
                  "}"
                ]
              }
            }
          ],
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/messages/scheduled",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "messages",
                "scheduled"
              ],
              "query": [
                {
                  "key": "status",
                  "value": "pending",
                  "disabled": true,
                  "description": "Filtra por estado."
                },
                {
                  "key": "limit",
                  "value": "50",
                  "disabled": true,
                  "description": "Itens por página."
                },
                {
                  "key": "offset",
                  "value": "0",
                  "disabled": true,
                  "description": "Quantos itens pular. É com ele que se pagina."
                }
              ]
            },
            "description": "Mensagens agendadas da conta, das mais próximas de sair para as mais distantes.\nInclui as já enviadas, as canceladas e as que falharam — é o histórico completo."
          },
          "response": []
        },
        {
          "id": "089a9acb-ba5f-5de3-a3ae-322303a746a5",
          "name": "Consultar um agendamento",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/messages/scheduled/:id",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "messages",
                "scheduled",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{scheduledMessageId}}"
                }
              ]
            },
            "description": "Estado de uma mensagem agendada. Depois de enviada, `messageId` traz o `wamid`\npara acompanhar a entrega em `GET /messages/status/{messageId}`."
          },
          "response": []
        },
        {
          "id": "35298a9e-148c-5772-a599-d98a101e1c47",
          "name": "Cancelar um agendamento",
          "request": {
            "method": "DELETE",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/messages/scheduled/:id",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "messages",
                "scheduled",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{scheduledMessageId}}"
                }
              ]
            },
            "description": "Cancela antes da hora. Vale mesmo com o job já na fila: o worker relê o registro\nantes de enviar. Uma mensagem já enviada responde `404`."
          },
          "response": []
        },
        {
          "id": "640d6d54-b367-5781-a5e2-1c0be60327ca",
          "name": "Estado de entrega",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/messages/status/:messageId",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "messages",
                "status",
                ":messageId"
              ],
              "variable": [
                {
                  "key": "messageId",
                  "value": "{{messageId}}",
                  "description": "WAMID devolvido no envio."
                }
              ]
            },
            "description": "Último estado conhecido de uma mensagem enviada, pelo WAMID.\n\nO `201` do envio diz apenas que o WhatsApp **aceitou** a mensagem — o resultado\nchega depois, pelo webhook `messages`. Fora da janela de 24 horas, por exemplo,\num texto livre é aceito e reprovado segundos depois com o código `131047`: quem\ntrata o `201` como sucesso final acha que enviou algo que nunca chegou.\n\nA resposta sai do mesmo espelho de `GET /events`, então não custa chamada na Meta\nnem cota de envio. `status: null` significa que nenhum status chegou ainda\n(costuma levar segundos) ou que os webhooks da conta não estão sendo entregues."
          },
          "response": []
        }
      ]
    },
    {
      "id": "ad061c59-e977-5b45-a94a-ecad8f55209c",
      "name": "Templates",
      "description": "Gestão dos templates de mensagem. Templates pertencem à **WABA** (conta\nempresarial), não a um número — use `GET /me` para descobrir seu `waba_id`.\n\n## Espelho local e sincronização\n\nMantemos um espelho dos seus templates para que a listagem seja instantânea.\nEle é atualizado por webhook sempre que a Meta muda o status de um template e,\nalém disso, sincronizado sob demanda quando fica mais velho que **15 minutos**.\n\nUse `refresh=true` para forçar a sincronização e `refresh=false` para servir só\no cache.\n\n## Variáveis e exemplos\n\nTodo template com variáveis precisa declarar exemplos — a Meta rejeita sem\neles. As regras validadas antes do envio:\n\n- Variáveis posicionais (`{{1}}`, `{{2}}`) precisam ser sequenciais e sem\n  lacunas.\n- Não misture o formato posicional com o nomeado (`{{nome}}`) no mesmo template.\n- O header de texto aceita **no máximo uma** variável.\n- O footer **não aceita** variáveis.\n- Botão de URL com variável exige um exemplo de URL completa.",
      "item": [
        {
          "id": "5c6781e7-9cea-5810-aa74-b3d68f5e7d0f",
          "name": "Listar templates",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "if (pm.response.code === 200 && !pm.collectionVariables.get('templateName')) {",
                  "  const json = pm.response.json();",
                  "  const first = json && Array.isArray(json.data) && json.data[0];",
                  "  if (first && first.name) pm.collectionVariables.set('templateName', first.name);",
                  "}"
                ]
              }
            }
          ],
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/templates",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "templates"
              ],
              "query": [
                {
                  "key": "wabaId",
                  "value": "texto",
                  "disabled": true,
                  "description": "Conta empresarial alvo. Se omitida, usa a WABA ativa mais recente."
                },
                {
                  "key": "status",
                  "value": "APPROVED",
                  "disabled": true,
                  "description": "Filtra pelo status de aprovação na Meta."
                },
                {
                  "key": "limit",
                  "value": "100",
                  "disabled": true
                },
                {
                  "key": "refresh",
                  "value": "true",
                  "disabled": true,
                  "description": "`true` força a sincronização com a Meta, `false` serve apenas o cache.\nOmitido, sincroniza só se o espelho estiver velho."
                },
                {
                  "key": "includeDeleted",
                  "value": "false",
                  "disabled": true,
                  "description": "Inclui os templates removidos, com `deleted_at` preenchido."
                }
              ]
            },
            "description": "Lista os templates da WABA a partir do espelho local. Se o espelho estiver\nmais velho que 15 minutos, uma sincronização com a Meta acontece antes da\nresposta.\n\nOs campos `stale` e `syncedAt` dizem se o que você recebeu está fresco. Quando\numa sincronização roda, o resumo dela vem em `sync`; se ela falhar, o motivo\nvem em `syncError` — mas os dados em cache ainda são devolvidos."
          },
          "response": []
        },
        {
          "id": "42145248-8791-5f0c-a0fb-3f30a5f234cb",
          "name": "Criar template",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const json = pm.response.json();",
                  "const value = json && json.data && json.data.name;",
                  "if (pm.response.code < 300 && value) pm.collectionVariables.set('templateName', value);"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"name\": \"confirmacao_pedido\",\n  \"category\": \"UTILITY\",\n  \"language\": \"pt_BR\",\n  \"components\": [\n    {\n      \"type\": \"BODY\",\n      \"text\": \"Olá {{1}}, seu pedido {{2}} foi confirmado.\",\n      \"example\": {\n        \"body_text\": [\n          [\n            \"Maria\",\n            \"1042\"\n          ]\n        ]\n      }\n    },\n    {\n      \"type\": \"FOOTER\",\n      \"text\": \"Joinotify\"\n    }\n  ]\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/templates",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "templates"
              ]
            },
            "description": "Cria um template na Meta. Ele nasce com status `PENDING` e a aprovação leva de\nalguns minutos a algumas horas — o resultado chega pelo webhook\n`message_template_status_update`.\n\nAntes de mandar para a Meta, validamos os componentes localmente e devolvemos\n`422 invalid_request` com o campo `issues` apontando o problema. Isso evita o\nciclo lento de submeter, esperar e ser rejeitado.\n\n### O que é validado\n\n- Variáveis sem exemplo declarado\n- Exemplos com valor vazio\n- Lacunas na numeração posicional (`{{1}}`, `{{3}}` sem `{{2}}`)\n- Mistura de formato posicional e nomeado no mesmo template\n- Mais de uma variável no header de texto\n- Qualquer variável no footer\n- Botão de URL com variável e sem exemplo de URL\n- Identificador inválido em variável nomeada\n- `parameterFormat` declarado que contradiz o texto\n\n### A partir da biblioteca da Meta\n\nEm vez de `components`, você pode mandar `libraryTemplateName` com o nome de um\nitem de `GET /templates/library`. Aí o texto é o da Meta e não passa por\nvalidação nenhuma daqui — o que você informa é só o que o modelo pede (URL do\nbotão, telefone). Os dois caminhos são excludentes: mandar os dois é `422`."
          },
          "response": []
        },
        {
          "id": "0beb4a2c-d101-5ab4-a573-57b34edbbd9f",
          "name": "Editar template",
          "request": {
            "method": "PUT",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"language\": \"pt_BR\",\n  \"components\": [\n    {\n      \"type\": \"BODY\",\n      \"text\": \"Oi {{1}}, seu pedido {{2}} saiu para entrega.\",\n      \"example\": {\n        \"body_text\": [\n          [\n            \"Maria\",\n            \"1042\"\n          ]\n        ]\n      }\n    }\n  ]\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/templates/:name",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "templates",
                ":name"
              ],
              "variable": [
                {
                  "key": "name",
                  "value": "{{templateName}}",
                  "description": "Nome do template."
                }
              ]
            },
            "description": "Substitui os componentes de um template existente. Só o corpo muda: **nome,\nidioma e categoria são imutáveis** na Meta — para mudar qualquer um deles,\ncrie outro template.\n\nA edição devolve o template para a fila de revisão (`PENDING`). Enquanto ela\ncorre, os envios continuam usando a versão aprovada anterior, então nada para\nde funcionar no meio do caminho.\n\n### Antes de chamar a Meta\n\n- Só templates em `APPROVED`, `REJECTED` ou `PAUSED` podem ser editados. Em\n  revisão (`PENDING`) a resposta é `422 template_not_editable`.\n- O `language` só é obrigatório quando o mesmo nome existe em mais de um\n  idioma — cada idioma é um template separado na Meta.\n- Os componentes passam pelas mesmas validações de `POST /templates`\n  (exemplo por variável, numeração sem buraco, rodapé sem variável…).\n- O formato das variáveis (numerado × nomeado) é fixado na criação e não\n  pode mudar numa edição.\n\nA Meta troca a **lista inteira** de componentes: o que não for enviado\ndesaparece. Para preservar botões ou um cabeçalho de mídia, reenvie esses\ncomponentes como vieram em `GET /templates`."
          },
          "response": []
        },
        {
          "id": "3c505e1a-ede4-52c2-ac0b-61dd5ea8c0f4",
          "name": "Remover template",
          "request": {
            "method": "DELETE",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/templates/:name",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "templates",
                ":name"
              ],
              "query": [
                {
                  "key": "wabaId",
                  "value": "texto",
                  "disabled": true,
                  "description": "Conta empresarial alvo. Se omitida, usa a WABA ativa mais recente."
                }
              ],
              "variable": [
                {
                  "key": "name",
                  "value": "{{templateName}}",
                  "description": "Nome do template."
                }
              ]
            },
            "description": "Remove o template na Meta e marca o espelho local como excluído.\n\nA remoção vale para **todos os idiomas** daquele nome. Mensagens já enviadas\ncom esse template continuam nas conversas."
          },
          "response": []
        },
        {
          "id": "bd42a132-b2f4-58e9-abf4-3f8501009e8c",
          "name": "Subir amostra de cabeçalho",
          "request": {
            "method": "POST",
            "header": [],
            "body": {
              "mode": "formdata",
              "formdata": [
                {
                  "key": "file",
                  "type": "file",
                  "src": []
                },
                {
                  "key": "format",
                  "type": "text",
                  "value": "IMAGE"
                },
                {
                  "key": "wabaId",
                  "type": "text",
                  "value": "texto",
                  "disabled": true
                },
                {
                  "key": "fileName",
                  "type": "text",
                  "value": "texto",
                  "disabled": true
                }
              ]
            },
            "url": {
              "raw": "{{baseUrl}}/templates/media",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "templates",
                "media"
              ]
            },
            "description": "Sobe o arquivo de exemplo do cabeçalho de um template e devolve o `handle` para\nusar em `POST /templates`.\n\nLimites da Meta: imagem JPEG/PNG até 5 MB, vídeo MP4/3GPP até 16 MB, documento PDF\naté 20 MB. Conferimos antes de gastar a banda do upload."
          },
          "response": []
        },
        {
          "id": "9354fc78-b632-54c4-a074-164df531bd8b",
          "name": "Buscar na biblioteca da Meta",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/templates/library",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "templates",
                "library"
              ],
              "query": [
                {
                  "key": "wabaId",
                  "value": "texto",
                  "disabled": true,
                  "description": "Conta empresarial alvo. Se omitida, usa a WABA ativa mais recente."
                },
                {
                  "key": "search",
                  "value": "entrega",
                  "disabled": true,
                  "description": "Trecho procurado no nome e no texto dos modelos."
                },
                {
                  "key": "language",
                  "value": "texto",
                  "disabled": true,
                  "description": "Código de idioma da Meta (`pt_BR`, `en_US`…)."
                },
                {
                  "key": "topic",
                  "value": "texto",
                  "disabled": true,
                  "description": "Assunto do modelo, como a Meta o classifica (`ORDER_MANAGEMENT`…)."
                },
                {
                  "key": "usecase",
                  "value": "texto",
                  "disabled": true,
                  "description": "Caso de uso (`DELIVERY_UPDATE`…)."
                },
                {
                  "key": "industry",
                  "value": "texto",
                  "disabled": true,
                  "description": "Setor (`E_COMMERCE`…)."
                },
                {
                  "key": "limit",
                  "value": "50",
                  "disabled": true
                },
                {
                  "key": "after",
                  "value": "texto",
                  "disabled": true,
                  "description": "Cursor devolvido em `paging.after` na página anterior."
                },
                {
                  "key": "refresh",
                  "value": "false",
                  "disabled": true,
                  "description": "`true` ignora o cache e busca direto na Meta."
                }
              ]
            },
            "description": "Busca no catálogo de modelos prontos da Meta — textos escritos por ela para os\ncasos mais comuns: lembrete de pagamento, confirmação de pedido, atualização\nde entrega, código de verificação.\n\nO que vem aqui **não são templates da sua conta**, é o catálogo. Para virar um\ntemplate, chame `POST /templates` com `libraryTemplateName` igual ao `name` do\nitem escolhido.\n\nDuas coisas que costumam ser mal entendidas:\n\n- **O texto não é editável.** Você preenche apenas o que o item pede —\n  `libraryTemplateButtonInputs` (URL, telefone) e `libraryTemplateBodyInputs`.\n  Para escrever o seu próprio texto, é o `POST /templates` com `components`.\n- **Não é aprovação garantida.** O template nasce `PENDING` como qualquer\n  outro; partir de um modelo pronto costuma acelerar a revisão, não dispensá-la.\n\nO catálogo é o mesmo para todas as contas e muda raramente, então a resposta\nsai de um cache compartilhado de 6 horas. `cached` diz de onde ela veio e\n`refresh=true` ignora o cache."
          },
          "response": []
        },
        {
          "id": "a8e36875-ab5f-5b49-afbc-f1915c21ffc8",
          "name": "Sincronizar templates",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"all\": true\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/templates/sync",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "templates",
                "sync"
              ]
            },
            "description": "Reconcilia o espelho local com a Meta: cria os que faltam, atualiza os que\nmudaram e remove os que não existem mais.\n\nSó é necessário em situações específicas — templates criados direto no\nBusiness Manager, ou suspeita de que um webhook se perdeu. No dia a dia, o\nespelho se mantém sozinho.\n\nSe uma sincronização da mesma WABA já estiver rodando, a resposta é `202` e\nnada é disparado em duplicidade."
          },
          "response": []
        }
      ]
    },
    {
      "id": "235b1ec0-be5d-5275-a2e0-c8e6fd1282b6",
      "name": "Contatos",
      "description": "A base de contatos da conta: criar, editar, apagar, registrar consentimento, unir\nduplicados e importar em lote. Uma API key restrita a alguns números enxerga\nsó os contatos que têm conversa nesses números, e recebe `403` no que é da base inteira —\nexportar, importar, criar, apagar, unir, opt-in e as definições de campos e tags.",
      "item": [
        {
          "id": "ad6bf7a8-1e9b-544d-a4dc-c6af95c12b6b",
          "name": "Listar contatos",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "if (pm.response.code === 200 && !pm.collectionVariables.get('contactId')) {",
                  "  const json = pm.response.json();",
                  "  const first = json && Array.isArray(json.data) && json.data[0];",
                  "  if (first && first.id) pm.collectionVariables.set('contactId', first.id);",
                  "}"
                ]
              }
            }
          ],
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/contacts",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "contacts"
              ],
              "query": [
                {
                  "key": "limit",
                  "value": "50",
                  "disabled": true,
                  "description": "Itens por página."
                },
                {
                  "key": "offset",
                  "value": "0",
                  "disabled": true,
                  "description": "Quantos itens pular. É com ele que se pagina."
                },
                {
                  "key": "sort",
                  "value": "recent",
                  "disabled": true,
                  "description": "`recent`: mais novos primeiro. `name`: por nome. `last_inbound`: quem escreveu por último primeiro."
                },
                {
                  "key": "q",
                  "value": "texto",
                  "disabled": true,
                  "description": "Busca por nome, e-mail ou telefone (pelos dígitos, a partir de 4)."
                },
                {
                  "key": "tagId",
                  "value": "texto",
                  "disabled": true,
                  "description": "Só contatos com esta tag."
                },
                {
                  "key": "optInStatus",
                  "value": "opted_in",
                  "disabled": true,
                  "description": "Situação do consentimento de marketing."
                },
                {
                  "key": "source",
                  "value": "manual",
                  "disabled": true,
                  "description": "Como o contato entrou na base."
                },
                {
                  "key": "audienceId",
                  "value": "texto",
                  "disabled": true,
                  "description": "Só contatos que o público salvo seleciona."
                },
                {
                  "key": "filter",
                  "value": "texto",
                  "disabled": true,
                  "description": "Filtro avançado: a árvore de condições de um público, em JSON. Veja o schema `AudienceFilter`."
                }
              ]
            },
            "description": "A base de contatos, paginada. Todos os filtros se somam (E).\n\nCom uma API key restrita a alguns números, a lista traz só os contatos que têm conversa nesses números."
          },
          "response": []
        },
        {
          "id": "7940281d-009a-588f-a8ce-44ac4c45cccd",
          "name": "Criar contato",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const json = pm.response.json();",
                  "const value = json && json.data && json.data.id;",
                  "if (pm.response.code < 300 && value) pm.collectionVariables.set('contactId', value);"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"phone\": \"+5541987111527\",\n  \"firstName\": \"Ana\",\n  \"lastName\": \"Souza\",\n  \"email\": \"ana@exemplo.com\",\n  \"locale\": \"pt-BR\",\n  \"attributes\": {\n    \"cidade\": \"Curitiba\"\n  },\n  \"optIn\": {\n    \"evidence\": \"Formulário de cadastro em https://loja.exemplo.com\"\n  }\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/contacts",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "contacts"
              ],
              "query": [
                {
                  "key": "upsert",
                  "value": "true",
                  "disabled": true,
                  "description": "Atualiza o contato quando ele já existe, em vez de responder `409`."
                }
              ]
            },
            "description": "Cria um contato a partir de um telefone ou de um BSUID. O telefone é normalizado para\nE.164 e guardado **sem** o `+`; sem código de país, informe `defaultCountry`.\n\nCom `?upsert=true`, um contato que já existe é atualizado em vez de responder `409` —\ne aí a resposta é `200`, `optIn` é ignorado e `tagIds` substitui as tags. Mande\n`optIn` com a evidência do consentimento para criar o contato já apto a receber marketing.\n\nUma API key restrita a alguns números recebe `403`: esta operação é da base inteira."
          },
          "response": []
        },
        {
          "id": "9af3fd67-c8d3-50ec-aa6f-2096af659181",
          "name": "Criar ou atualizar contatos em lote",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"contacts\": [\n    {\n      \"phone\": \"+5541987111527\",\n      \"firstName\": \"Ana\",\n      \"email\": \"ana@exemplo.com\",\n      \"tags\": [\n        \"Clientes\"\n      ]\n    },\n    {\n      \"phone\": \"+5511912345678\",\n      \"name\": \"Bruno Lima\",\n      \"tags\": [\n        \"Clientes\"\n      ]\n    }\n  ],\n  \"options\": {\n    \"onDuplicate\": \"update\",\n    \"defaultCountry\": \"BR\"\n  }\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/contacts/batch",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "contacts",
                "batch"
              ]
            },
            "description": "Até 500 contatos por chamada, cada um criado ou atualizado pelo telefone ou BSUID. A\nresposta é `200` mesmo quando linhas falham: o resultado de cada uma vem em `results`,\nna ordem do envio.\n\nNuma atualização, só valores preenchidos sobrescrevem e as tags são **somadas**. Com\n`options.optIn`, contatos novos nascem com consentimento e existentes só o ganham se\nainda estavam em `unknown` — um opt-out nunca é desfeito. O lote não dispara webhooks.\n\nUma API key restrita a alguns números recebe `403`: esta operação é da base inteira."
          },
          "response": []
        },
        {
          "id": "ddc7d95e-42f9-5638-ac7b-0477fb766a6d",
          "name": "Sincronizar os contatos de um site",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}",
                "disabled": true,
                "description": "Identificador da operação, escolhido por você — de 8 a 128 caracteres entre letras,\ndígitos, `_`, `-`, `.` e `:`. Repetir a chamada com o mesmo valor e o mesmo corpo\ndevolve a primeira resposta em vez de executar de novo. Vale por 24 horas, por conta."
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"contacts\": [\n    {\n      \"ref\": {\n        \"kind\": \"wc_customer\",\n        \"id\": \"42\"\n      },\n      \"phone\": \"+5511987654321\",\n      \"country\": \"BR\",\n      \"firstName\": \"Ana\",\n      \"lastName\": \"Souza\",\n      \"email\": \"ana@example.com\",\n      \"tags\": [\n        \"Cliente WooCommerce\"\n      ],\n      \"consent\": {\n        \"status\": \"opted_in\",\n        \"evidence\": \"Caixa marcada no checkout de https://loja.example.com — pedido 1042\",\n        \"at\": \"2026-09-20T10:15:00-03:00\"\n      },\n      \"occurredAt\": \"2026-09-24T14:32:05-03:00\"\n    }\n  ],\n  \"options\": {\n    \"triggers\": false,\n    \"defaultCountry\": \"BR\"\n  }\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/contacts/sync",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "contacts",
                "sync"
              ]
            },
            "description": "Os clientes de um site conectado, até 500 por chamada. É o que o plugin do WordPress\nchama para trazer os usuários, clientes e leads do site — e qualquer plataforma própria\ncom a API key de um site conectado pode chamar também. A resposta é `200` mesmo quando\nlinhas falham: o resultado de cada uma vem em `results`, na ordem do envio.\n\n`POST /contacts/batch` é uma planilha enviada uma vez. Esta rota é o contrário: um\nsistema que reporta as mesmas pessoas de novo e de novo, e por isso as regras só somam,\nnunca destroem:\n\n- o contato é achado primeiro por quem ele é **no site** (`ref`: o usuário 42 do\n  WordPress), depois pelo telefone. Quem trocou de número continua sendo o mesmo contato;\n  se o número novo já é de outro contato, nada é unido e a linha volta com\n  `phone_conflict`;\n- sem telefone e sem vínculo com o site, ninguém é criado (`no_phone`, `invalid_phone`);\n- tags só entram, pelo nome, e as que não existem são criadas. Para tirar uma, use\n  `removeTags`;\n- nome, e-mail e campos personalizados só preenchem o que está vazio: o que alguém\n  digitou no painel vence o que o site reporta. Os campos que o próprio site calcula\n  (os `wc_…` do WooCommerce) sobrescrevem — a menos que `occurredAt` seja mais antigo\n  que o último aplicado para aquele vínculo (`stale_snapshot`);\n- um opt-out dado no site sempre vale. O consentimento só passa de `unknown` para\n  `opted_in`, com evidência, e nunca por cima de um opt-out (`kept_opt_out`) ou de uma\n  supressão (`kept_suppression`);\n- um valor para um campo que a conta não tem, ou do tipo errado, é descartado e aparece\n  em `warnings` — o resto da linha é aplicado;\n- contatos novos contam no teto do plano (`contact_limit_reached`).\n\nCom `options.triggers` em `false` — o padrão, o de uma carga inicial — nada dispara:\nnenhum fluxo começa e nenhum webhook `contact.created` sai. Uma carga de dez mil clientes\nnão pode cumprimentar dez mil pessoas. Mande `true` para o que acabou de acontecer no site.\n\n**Idempotência.** Com o header `Idempotency-Key`, um lote repetido depois de uma conexão\nque caiu devolve o primeiro resultado, com `Idempotent-Replayed: true`, em vez de ser\naplicado duas vezes. A mesma chave com outro corpo é recusada com\n`422 idempotency_key_reused`; enquanto a primeira requisição ainda roda, a repetição\nrecebe `409 idempotency_in_progress`.\n\nSó a API key de um site conectado sincroniza — ela vem com a permissão `contacts:sync`.\nUma API key comum recebe `404 site_not_found`, e uma API key restrita a alguns números,\n`403`."
          },
          "response": []
        },
        {
          "id": "a45a30c8-40e2-5ba9-af13-a55e50aa63cf",
          "name": "Exportar contatos em CSV",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/contacts/export",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "contacts",
                "export"
              ],
              "query": [
                {
                  "key": "q",
                  "value": "texto",
                  "disabled": true,
                  "description": "Busca por nome, e-mail ou telefone (pelos dígitos, a partir de 4)."
                },
                {
                  "key": "tagId",
                  "value": "texto",
                  "disabled": true,
                  "description": "Só contatos com esta tag."
                },
                {
                  "key": "optInStatus",
                  "value": "opted_in",
                  "disabled": true,
                  "description": "Situação do consentimento de marketing."
                },
                {
                  "key": "source",
                  "value": "manual",
                  "disabled": true,
                  "description": "Como o contato entrou na base."
                },
                {
                  "key": "audienceId",
                  "value": "texto",
                  "disabled": true,
                  "description": "Só contatos que o público salvo seleciona."
                },
                {
                  "key": "filter",
                  "value": "texto",
                  "disabled": true,
                  "description": "Filtro avançado: a árvore de condições de um público, em JSON. Veja o schema `AudienceFilter`."
                }
              ]
            },
            "description": "A base inteira — ou o que os filtros selecionarem — num CSV, sem paginação. Uma coluna\npor campo personalizado, depois das fixas. O arquivo começa com BOM UTF-8, o telefone vai\nsem `+` e células que começam com `=`, `+`, `-` ou `@` ganham um `'` na frente.\n\nUma API key restrita a alguns números recebe `403`: esta operação é da base inteira."
          },
          "response": []
        },
        {
          "id": "7d8f5758-c8fd-5f47-a650-2b0d1d26b0e5",
          "name": "Listar importações",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "if (pm.response.code === 200 && !pm.collectionVariables.get('importId')) {",
                  "  const json = pm.response.json();",
                  "  const first = json && Array.isArray(json.data) && json.data[0];",
                  "  if (first && first.id) pm.collectionVariables.set('importId', first.id);",
                  "}"
                ]
              }
            }
          ],
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/contacts/imports",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "contacts",
                "imports"
              ],
              "query": [
                {
                  "key": "limit",
                  "value": "50",
                  "disabled": true,
                  "description": "Itens por página."
                },
                {
                  "key": "offset",
                  "value": "0",
                  "disabled": true,
                  "description": "Quantos itens pular. É com ele que se pagina."
                }
              ]
            },
            "description": ""
          },
          "response": []
        },
        {
          "id": "5d3f845e-8b19-5883-a94e-aa5f15bba616",
          "name": "Abrir uma importação",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const json = pm.response.json();",
                  "const value = json && json.data && json.data.id;",
                  "if (pm.response.code < 300 && value) pm.collectionVariables.set('importId', value);"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"filename\": \"contatos.csv\",\n  \"total\": 2\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/contacts/imports",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "contacts",
                "imports"
              ]
            },
            "description": "Um registro que acompanha uma importação grande feita em vários lotes: mande o `id` em\n`options.importId` de cada `POST /contacts/batch` e os contadores se somam aqui. Feche\ncom `PATCH` quando terminar.\n\nUma API key restrita a alguns números recebe `403`: esta operação é da base inteira."
          },
          "response": []
        },
        {
          "id": "89fe9bb9-da39-5f27-a190-06c01fa103b5",
          "name": "Consultar uma importação",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/contacts/imports/:importId",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "contacts",
                "imports",
                ":importId"
              ],
              "variable": [
                {
                  "key": "importId",
                  "value": "{{importId}}"
                }
              ]
            },
            "description": ""
          },
          "response": []
        },
        {
          "id": "8d144ed3-d587-553e-af3c-a067da4f5086",
          "name": "Encerrar uma importação",
          "request": {
            "method": "PATCH",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"status\": \"completed\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/contacts/imports/:importId",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "contacts",
                "imports",
                ":importId"
              ],
              "variable": [
                {
                  "key": "importId",
                  "value": "{{importId}}"
                }
              ]
            },
            "description": "Marca a importação como `completed` ou `failed`. Só uma importação ainda em `processing` pode ser encerrada.\n\nUma API key restrita a alguns números recebe `403`: esta operação é da base inteira."
          },
          "response": []
        },
        {
          "id": "1d29997b-3320-5fe9-aa4c-526977f5fe37",
          "name": "Consultar um contato",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/contacts/:id",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "contacts",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{contactId}}"
                }
              ]
            },
            "description": "O contato, com as linhas da lista de supressão que batem com o telefone ou o BSUID dele.\n\nCom uma API key restrita a alguns números, um contato sem conversa nesses números responde `404`, como um que não existe."
          },
          "response": []
        },
        {
          "id": "ceda5438-f6b4-5769-a7c6-6fa67e1d0529",
          "name": "Editar um contato",
          "request": {
            "method": "PATCH",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"firstName\": \"Ana Maria\",\n  \"attributes\": {\n    \"cidade\": \"São Paulo\"\n  }\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/contacts/:id",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "contacts",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{contactId}}"
                }
              ]
            },
            "description": "Campo ausente fica como está; `null` apaga. `attributes` é um patch sobre os valores\nguardados, e `tagIds` é o conjunto **completo** de tags. O consentimento não se edita\naqui — use `opt-in` e `opt-out`.\n\nCom uma API key restrita a alguns números, um contato sem conversa nesses números responde `404`, como um que não existe."
          },
          "response": []
        },
        {
          "id": "f43e9dcd-8a2b-552a-ab0f-0eb26e3b5031",
          "name": "Apagar um contato",
          "request": {
            "method": "DELETE",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/contacts/:id",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "contacts",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{contactId}}"
                }
              ]
            },
            "description": "Apaga o contato de vez, com as conversas, mensagens, tags e histórico — é o pedido de\neliminação da LGPD. As linhas da lista de supressão ficam, sem a identidade, e os\ndestinatários de campanhas são anonimizados.\n\nUma API key restrita a alguns números recebe `403`: esta operação é da base inteira."
          },
          "response": []
        },
        {
          "id": "1883b02c-7acb-5b52-a9bc-49ff96af318c",
          "name": "Registrar opt-in",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"evidence\": \"Aceitou pelo WhatsApp em 29/09/2026\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/contacts/:id/opt-in",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "contacts",
                ":id",
                "opt-in"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{contactId}}"
                }
              ]
            },
            "description": "Registra o consentimento de marketing, com a evidência de como foi obtido. Tira o\ncontato da lista de supressão **só** quando o motivo era um opt-out anterior. Dispara\n`contact.opted_in`.\n\nUma API key restrita a alguns números recebe `403`: esta operação é da base inteira."
          },
          "response": []
        },
        {
          "id": "6ecb8ac5-8d53-5d2f-ac7b-b5488c8d4cc1",
          "name": "Registrar opt-out",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"reason\": \"Pediu para sair\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/contacts/:id/opt-out",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "contacts",
                ":id",
                "opt-out"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{contactId}}"
                }
              ]
            },
            "description": "Tira o consentimento e põe o telefone e o BSUID do contato na lista de supressão. Dispara `contact.opted_out`.\n\nCom uma API key restrita a alguns números, um contato sem conversa nesses números responde `404`, como um que não existe."
          },
          "response": []
        },
        {
          "id": "a718bbdd-2711-54b4-a3c4-e7850bd0d597",
          "name": "Unir contatos duplicados",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"duplicateId\": \"{{duplicateContactId}}\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/contacts/:id/merge",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "contacts",
                ":id",
                "merge"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{contactId}}"
                }
              ]
            },
            "description": "O contato do caminho sobrevive; `duplicateId` é apagado depois de ter conversas, tags,\nhistórico e campanhas movidos para ele. Nos campos, vale o do sobrevivente e o do\nduplicado só preenche vazios. No consentimento, o opt-out vence.\n\nUma API key restrita a alguns números recebe `403`: esta operação é da base inteira."
          },
          "response": []
        },
        {
          "id": "4235c08b-4b8a-5374-a39b-b737bcfd018a",
          "name": "Histórico do contato",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/contacts/:id/activity",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "contacts",
                ":id",
                "activity"
              ],
              "query": [
                {
                  "key": "limit",
                  "value": "50",
                  "disabled": true,
                  "description": "Itens por página."
                },
                {
                  "key": "offset",
                  "value": "0",
                  "disabled": true,
                  "description": "Quantos itens pular. É com ele que se pagina."
                }
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{contactId}}"
                }
              ]
            },
            "description": "O que aconteceu com o contato, do mais recente ao mais antigo: criação, edições, tags, consentimento, uniões e cliques em campanha.\n\nCom uma API key restrita a alguns números, um contato sem conversa nesses números responde `404`, como um que não existe."
          },
          "response": []
        },
        {
          "id": "aab5af17-243c-56c6-ae49-ae39dc667b4a",
          "name": "Exportar os dados de um contato",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/contacts/:id/export",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "contacts",
                ":id",
                "export"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{contactId}}"
                }
              ]
            },
            "description": "Tudo o que a conta guarda sobre o contato, num JSON para download — o pedido de acesso da LGPD. Até 10.000 mensagens por conversa.\n\nUma API key restrita a alguns números recebe `403`: esta operação é da base inteira."
          },
          "response": []
        }
      ]
    },
    {
      "id": "c6b691db-8fc3-5b38-a944-7abd91e5c019",
      "name": "Campos e tags",
      "description": "Campos personalizados dos contatos e as tags que os organizam.",
      "item": [
        {
          "id": "c4576e54-714e-5682-a2c7-3a8ce42f0cde",
          "name": "Listar campos personalizados",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "if (pm.response.code === 200 && !pm.collectionVariables.get('fieldId')) {",
                  "  const json = pm.response.json();",
                  "  const first = json && Array.isArray(json.data) && json.data[0];",
                  "  if (first && first.id) pm.collectionVariables.set('fieldId', first.id);",
                  "}"
                ]
              }
            }
          ],
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/contacts/fields",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "contacts",
                "fields"
              ],
              "query": [
                {
                  "key": "archived",
                  "value": "true",
                  "disabled": true,
                  "description": "`true` inclui os arquivados."
                }
              ]
            },
            "description": ""
          },
          "response": []
        },
        {
          "id": "dce9496d-aceb-5630-a6ff-ba0e4f8f0c3b",
          "name": "Criar campo personalizado",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const json = pm.response.json();",
                  "const value = json && json.data && json.data.id;",
                  "if (pm.response.code < 300 && value) pm.collectionVariables.set('fieldId', value);"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"key\": \"cidade\",\n  \"label\": \"Cidade\",\n  \"type\": \"text\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/contacts/fields",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "contacts",
                "fields"
              ]
            },
            "description": "Um campo novo para os contatos. `key` e `type` não mudam depois. Os tipos `select` e\n`multi_select` exigem `options`; os outros não aceitam.\n\nUma API key restrita a alguns números recebe `403`: esta operação é da base inteira."
          },
          "response": []
        },
        {
          "id": "8d66b6cd-10fb-5f72-a4e5-8fb52f2473bb",
          "name": "Editar campo personalizado",
          "request": {
            "method": "PATCH",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"label\": \"Cidade de entrega\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/contacts/fields/:fieldId",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "contacts",
                "fields",
                ":fieldId"
              ],
              "variable": [
                {
                  "key": "fieldId",
                  "value": "{{fieldId}}"
                }
              ]
            },
            "description": "Muda o rótulo, as opções (a lista inteira é substituída), a posição ou arquiva o campo. Um campo arquivado não aceita mais valores.\n\nUma API key restrita a alguns números recebe `403`: esta operação é da base inteira."
          },
          "response": []
        },
        {
          "id": "98e06852-a0c9-521f-a8e8-1cdc1994fced",
          "name": "Apagar campo personalizado",
          "request": {
            "method": "DELETE",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/contacts/fields/:fieldId?confirm=true",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "contacts",
                "fields",
                ":fieldId"
              ],
              "query": [
                {
                  "key": "confirm",
                  "value": "true",
                  "description": "Precisa ser `true`."
                }
              ],
              "variable": [
                {
                  "key": "fieldId",
                  "value": "{{fieldId}}"
                }
              ]
            },
            "description": "Apaga o campo e o valor dele em todos os contatos. Não tem volta, por isso exige `confirm=true`.\n\nUma API key restrita a alguns números recebe `403`: esta operação é da base inteira."
          },
          "response": []
        },
        {
          "id": "e90473f1-aa8c-5d7d-afb1-ad8f77476494",
          "name": "Listar tags de contato",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "if (pm.response.code === 200 && !pm.collectionVariables.get('tagId')) {",
                  "  const json = pm.response.json();",
                  "  const first = json && Array.isArray(json.data) && json.data[0];",
                  "  if (first && first.id) pm.collectionVariables.set('tagId', first.id);",
                  "}"
                ]
              }
            }
          ],
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/contacts/tags",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "contacts",
                "tags"
              ],
              "query": [
                {
                  "key": "limit",
                  "value": "200",
                  "disabled": true,
                  "description": "Itens por página."
                },
                {
                  "key": "offset",
                  "value": "0",
                  "disabled": true,
                  "description": "Quantos itens pular. É com ele que se pagina."
                },
                {
                  "key": "q",
                  "value": "texto",
                  "disabled": true
                }
              ]
            },
            "description": ""
          },
          "response": []
        },
        {
          "id": "a86461f3-ce7b-5a08-ac70-c896cf38229f",
          "name": "Criar tag de contato",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const json = pm.response.json();",
                  "const value = json && json.data && json.data.id;",
                  "if (pm.response.code < 300 && value) pm.collectionVariables.set('tagId', value);"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"name\": \"Clientes\",\n  \"color\": \"#22c55e\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/contacts/tags",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "contacts",
                "tags"
              ]
            },
            "description": "Uma API key restrita a alguns números recebe `403`: esta operação é da base inteira."
          },
          "response": []
        },
        {
          "id": "647d8e0f-a446-5c5e-ae6a-2a5172da4f83",
          "name": "Aplicar tag em massa",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"tagId\": \"{{tagId}}\",\n  \"action\": \"add\",\n  \"contactIds\": [\n    \"{{contactId}}\"\n  ]\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/contacts/tags/apply",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "contacts",
                "tags",
                "apply"
              ]
            },
            "description": "Põe ou tira uma tag de muitos contatos de uma vez: por lista de ids (até 1.000) ou pelos\nmesmos filtros de `GET /contacts` — um ou outro. `affected` conta só quem mudou. Não\ndispara fluxos nem webhooks.\n\nUma API key restrita a alguns números recebe `403`: esta operação é da base inteira."
          },
          "response": []
        },
        {
          "id": "3c34a85e-ef61-5b56-a962-9e7b507b2939",
          "name": "Editar tag de contato",
          "request": {
            "method": "PATCH",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"name\": \"Clientes VIP\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/contacts/tags/:tagId",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "contacts",
                "tags",
                ":tagId"
              ],
              "variable": [
                {
                  "key": "tagId",
                  "value": "{{tagId}}"
                }
              ]
            },
            "description": "Uma API key restrita a alguns números recebe `403`: esta operação é da base inteira."
          },
          "response": []
        },
        {
          "id": "c82af5c4-8ea0-59eb-af98-019be2a63812",
          "name": "Apagar tag de contato",
          "request": {
            "method": "DELETE",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/contacts/tags/:tagId",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "contacts",
                "tags",
                ":tagId"
              ],
              "variable": [
                {
                  "key": "tagId",
                  "value": "{{tagId}}"
                }
              ]
            },
            "description": "Apaga a tag e a tira de todos os contatos.\n\nUma API key restrita a alguns números recebe `403`: esta operação é da base inteira."
          },
          "response": []
        }
      ]
    },
    {
      "id": "82976361-3689-52da-a8b9-dbad34da644c",
      "name": "Supressões",
      "description": "A lista de supressão: números e BSUIDs que nunca recebem campanha de marketing,\ntenham o consentimento que tiverem.",
      "item": [
        {
          "id": "649a725c-c041-5a9b-a39d-f46602ed20a5",
          "name": "Listar supressões",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "if (pm.response.code === 200 && !pm.collectionVariables.get('suppressionId')) {",
                  "  const json = pm.response.json();",
                  "  const first = json && Array.isArray(json.data) && json.data[0];",
                  "  if (first && first.id) pm.collectionVariables.set('suppressionId', first.id);",
                  "}"
                ]
              }
            }
          ],
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/suppressions",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "suppressions"
              ],
              "query": [
                {
                  "key": "limit",
                  "value": "50",
                  "disabled": true,
                  "description": "Itens por página."
                },
                {
                  "key": "offset",
                  "value": "0",
                  "disabled": true,
                  "description": "Quantos itens pular. É com ele que se pagina."
                },
                {
                  "key": "reason",
                  "value": "opt_out",
                  "disabled": true
                },
                {
                  "key": "q",
                  "value": "texto",
                  "disabled": true,
                  "description": "Busca pelos dígitos do telefone ou pelo BSUID."
                }
              ]
            },
            "description": "Uma API key restrita a alguns números recebe `403`: a lista de supressão é da conta inteira."
          },
          "response": []
        },
        {
          "id": "2af78fd6-92a4-5fec-ac24-3a5857b24f83",
          "name": "Adicionar à lista de supressão",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const json = pm.response.json();",
                  "const value = json && json.data && json.data.id;",
                  "if (pm.response.code < 300 && value) pm.collectionVariables.set('suppressionId', value);"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"identity\": \"+5541987111527\",\n  \"note\": \"Pediu para não receber\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/suppressions",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "suppressions"
              ]
            },
            "description": "Adiciona um telefone ou BSUID com o motivo `manual`. Se a identidade já está na lista,\nnada muda e a linha existente volta, com o motivo original. Não altera o consentimento de\nnenhum contato.\n\nUma API key restrita a alguns números recebe `403`: a lista de supressão é da conta inteira."
          },
          "response": []
        },
        {
          "id": "a736b002-e434-5889-ab76-3e662dc77296",
          "name": "Remover da lista de supressão",
          "request": {
            "method": "DELETE",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/suppressions/:id",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "suppressions",
                ":id"
              ],
              "query": [
                {
                  "key": "confirm",
                  "value": "true",
                  "disabled": true,
                  "description": "Obrigatório (`true`) para os motivos `opt_out` e `meta_marketing_block`."
                }
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{suppressionId}}"
                }
              ]
            },
            "description": "Tira a identidade da lista. Linhas com motivo `opt_out` ou `meta_marketing_block`\nexigem `confirm=true`: a pessoa pediu para sair, ou a Meta está bloqueando marketing\npara ela. O contato continua em opt-out até um novo opt-in.\n\nUma API key restrita a alguns números recebe `403`: a lista de supressão é da conta inteira."
          },
          "response": []
        }
      ]
    },
    {
      "id": "60ca5cbe-47f7-5197-a18a-a84cb9ca176d",
      "name": "Públicos",
      "description": "Públicos salvos: um filtro sobre a base de contatos, com nome, para reaproveitar em campanhas.",
      "item": [
        {
          "id": "98a39754-9c70-5a54-ac48-56050c4d949c",
          "name": "Listar públicos",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "if (pm.response.code === 200 && !pm.collectionVariables.get('audienceId')) {",
                  "  const json = pm.response.json();",
                  "  const first = json && Array.isArray(json.data) && json.data[0];",
                  "  if (first && first.id) pm.collectionVariables.set('audienceId', first.id);",
                  "}"
                ]
              }
            }
          ],
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/audiences",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "audiences"
              ],
              "query": [
                {
                  "key": "limit",
                  "value": "50",
                  "disabled": true,
                  "description": "Itens por página."
                },
                {
                  "key": "offset",
                  "value": "0",
                  "disabled": true,
                  "description": "Quantos itens pular. É com ele que se pagina."
                },
                {
                  "key": "q",
                  "value": "texto",
                  "disabled": true,
                  "description": "Busca no nome."
                },
                {
                  "key": "archived",
                  "value": "true",
                  "disabled": true,
                  "description": "`true` lista só os arquivados."
                }
              ]
            },
            "description": "Os públicos salvos, sem as contagens recalculadas — só a última (`lastCount`).\n\nUma API key restrita a alguns números recebe `403`: públicos são filtros sobre a base inteira."
          },
          "response": []
        },
        {
          "id": "3ae96df3-7fe8-54bc-aef1-500052f86751",
          "name": "Criar público",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const json = pm.response.json();",
                  "const value = json && json.data && json.data.id;",
                  "if (pm.response.code < 300 && value) pm.collectionVariables.set('audienceId', value);"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"name\": \"Clientes de Curitiba\",\n  \"filter\": {\n    \"op\": \"and\",\n    \"rules\": [\n      {\n        \"type\": \"consent\",\n        \"op\": \"is\",\n        \"value\": \"opted_in\"\n      },\n      {\n        \"type\": \"field\",\n        \"key\": \"cidade\",\n        \"op\": \"eq\",\n        \"value\": \"Curitiba\"\n      }\n    ]\n  }\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/audiences",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "audiences"
              ]
            },
            "description": "Uma API key restrita a alguns números recebe `403`: públicos são filtros sobre a base inteira."
          },
          "response": []
        },
        {
          "id": "0c7fe88b-8bc6-53b1-a81d-10568d2eb444",
          "name": "Operadores de filtro de público",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/audiences/schema",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "audiences",
                "schema"
              ]
            },
            "description": "Os campos nativos que um filtro aceita e os operadores válidos para cada tipo de campo.\n\nUma API key restrita a alguns números recebe `403`: públicos são filtros sobre a base inteira."
          },
          "response": []
        },
        {
          "id": "a40f3844-4df0-5089-a10c-3a6aeff3ec37",
          "name": "Pré-visualizar público",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"filter\": {\n    \"op\": \"and\",\n    \"rules\": [\n      {\n        \"type\": \"consent\",\n        \"op\": \"is\",\n        \"value\": \"opted_in\"\n      },\n      {\n        \"type\": \"field\",\n        \"key\": \"cidade\",\n        \"op\": \"eq\",\n        \"value\": \"Curitiba\"\n      }\n    ]\n  }\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/audiences/preview",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "audiences",
                "preview"
              ]
            },
            "description": "Conta quem um filtro seleciona, por situação de consentimento, e devolve até 10 contatos de amostra. Não salva nada.\n\nUma API key restrita a alguns números recebe `403`: públicos são filtros sobre a base inteira."
          },
          "response": []
        },
        {
          "id": "80fd8848-8b86-58d6-a0d7-58eac86a5015",
          "name": "Consultar um público",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/audiences/:id",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "audiences",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{audienceId}}"
                }
              ]
            },
            "description": "O público com as contagens recalculadas agora.\n\nUma API key restrita a alguns números recebe `403`: públicos são filtros sobre a base inteira."
          },
          "response": []
        },
        {
          "id": "fcb48268-2bce-5a83-a58c-43ce19e2b8d6",
          "name": "Editar público",
          "request": {
            "method": "PATCH",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"filter\": {\n    \"op\": \"and\",\n    \"rules\": [\n      {\n        \"type\": \"consent\",\n        \"op\": \"is\",\n        \"value\": \"opted_in\"\n      },\n      {\n        \"type\": \"field\",\n        \"key\": \"cidade\",\n        \"op\": \"eq\",\n        \"value\": \"Curitiba\"\n      }\n    ]\n  }\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/audiences/:id",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "audiences",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{audienceId}}"
                }
              ]
            },
            "description": "Uma API key restrita a alguns números recebe `403`: públicos são filtros sobre a base inteira."
          },
          "response": []
        },
        {
          "id": "0766afd2-a652-5aad-a274-ed9046ae46a3",
          "name": "Apagar público",
          "request": {
            "method": "DELETE",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/audiences/:id",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "audiences",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{audienceId}}"
                }
              ]
            },
            "description": "Apaga o público. Uma campanha em rascunho que o usava passa a falhar na conferência com `audience_invalid`.\n\nUma API key restrita a alguns números recebe `403`: públicos são filtros sobre a base inteira."
          },
          "response": []
        }
      ]
    },
    {
      "id": "c8c33a60-ff44-5790-a59b-00029c145e71",
      "name": "Campanhas",
      "description": "Campanhas: um template aprovado enviado a um público, com agendamento, janela de envio\ne controle de vazão. Os envios acontecem num processo à parte e **não** gastam o limite de\nenvio da sua API key.",
      "item": [
        {
          "id": "2e360235-7b44-5abd-a8e4-8fa83c0cabaf",
          "name": "Listar campanhas",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "if (pm.response.code === 200 && !pm.collectionVariables.get('broadcastId')) {",
                  "  const json = pm.response.json();",
                  "  const first = json && Array.isArray(json.data) && json.data[0];",
                  "  if (first && first.id) pm.collectionVariables.set('broadcastId', first.id);",
                  "}"
                ]
              }
            }
          ],
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/broadcasts",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "broadcasts"
              ],
              "query": [
                {
                  "key": "limit",
                  "value": "50",
                  "disabled": true,
                  "description": "Itens por página."
                },
                {
                  "key": "offset",
                  "value": "0",
                  "disabled": true,
                  "description": "Quantos itens pular. É com ele que se pagina."
                },
                {
                  "key": "status",
                  "value": "draft",
                  "disabled": true
                },
                {
                  "key": "q",
                  "value": "texto",
                  "disabled": true,
                  "description": "Busca no nome."
                },
                {
                  "key": "phoneNumberId",
                  "value": "texto",
                  "disabled": true
                },
                {
                  "key": "archived",
                  "value": "true",
                  "disabled": true,
                  "description": "`true` lista só os arquivados."
                }
              ]
            },
            "description": "As campanhas da conta, das mais novas às mais antigas. Uma API key restrita a alguns números só vê as campanhas desses números."
          },
          "response": []
        },
        {
          "id": "5db1d9df-4944-5f1c-a75b-ecfd118ff47b",
          "name": "Criar campanha",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const json = pm.response.json();",
                  "const value = json && json.data && json.data.id;",
                  "if (pm.response.code < 300 && value) pm.collectionVariables.set('broadcastId', value);"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"name\": \"Black Friday\",\n  \"phoneNumberId\": \"{{phoneNumberId}}\",\n  \"templateName\": \"promo_black_friday\",\n  \"templateLanguage\": \"pt_BR\",\n  \"variables\": {\n    \"body\": {\n      \"1\": {\n        \"source\": \"contact\",\n        \"key\": \"first_name\",\n        \"fallback\": \"cliente\"\n      },\n      \"2\": {\n        \"source\": \"static\",\n        \"value\": \"BLACK20\"\n      }\n    }\n  },\n  \"audienceId\": \"{{audienceId}}\",\n  \"timezone\": \"America/Sao_Paulo\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/broadcasts",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "broadcasts"
              ]
            },
            "description": "Cria um rascunho. Só `name` é obrigatório: número, template, variáveis e público podem\nvir depois, por `PATCH`. A campanha só é conferida por inteiro na estimativa, no teste e\nno lançamento."
          },
          "response": []
        },
        {
          "id": "dc3214c1-3f34-5d89-a5f2-c8d6caeba4de",
          "name": "Subir mídia do cabeçalho da campanha",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "{{mediaContentType}}",
                "description": "application/octet-stream"
              },
              {
                "key": "X-File-Name",
                "value": "",
                "disabled": true,
                "description": "Nome do arquivo, codificado como URI."
              }
            ],
            "body": {
              "mode": "file",
              "file": {}
            },
            "url": {
              "raw": "{{baseUrl}}/broadcasts/media?phoneNumberId=texto",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "broadcasts",
                "media"
              ],
              "query": [
                {
                  "key": "phoneNumberId",
                  "value": "texto",
                  "description": "Número que vai enviar a campanha."
                }
              ]
            },
            "description": "Sobe para a Meta, pelo número da campanha, a imagem, o vídeo ou o documento do\ncabeçalho do template. Mande os bytes do arquivo no corpo, com o nome em `X-File-Name`,\ne use o `id` devolvido em `variables.headerMedia.id`. A Meta guarda a mídia por 30 dias."
          },
          "response": []
        },
        {
          "id": "dc278b97-b2c7-5078-a5db-e3e77dd30564",
          "name": "Consultar uma campanha",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/broadcasts/:id",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "broadcasts",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{broadcastId}}"
                }
              ]
            },
            "description": ""
          },
          "response": []
        },
        {
          "id": "eb97439a-ae45-5556-aa94-0270b0d301e6",
          "name": "Editar campanha",
          "request": {
            "method": "PATCH",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"name\": \"Black Friday — 2º lote\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/broadcasts/:id",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "broadcasts",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{broadcastId}}"
                }
              ]
            },
            "description": "Só rascunhos e campanhas agendadas podem ser editados. Editar uma campanha agendada a devolve para rascunho — ela precisa ser lançada de novo."
          },
          "response": []
        },
        {
          "id": "6df9552d-ab8a-56f6-a4e2-2229d511797d",
          "name": "Apagar campanha",
          "request": {
            "method": "DELETE",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/broadcasts/:id",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "broadcasts",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{broadcastId}}"
                }
              ]
            },
            "description": "Só rascunhos podem ser apagados. Para as outras, use o arquivamento."
          },
          "response": []
        },
        {
          "id": "efcd1f41-29fd-5b63-aa90-1650a943e877",
          "name": "Estimar alcance e custo",
          "request": {
            "method": "POST",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/broadcasts/:id/estimate",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "broadcasts",
                ":id",
                "estimate"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{broadcastId}}"
                }
              ]
            },
            "description": "Confere a campanha inteira e calcula quem ela alcançaria agora: quantos contatos, quantos\nficam de fora e por quê, o teto de destinatários, a cota do plano, o limite de mensagens\ndo número na Meta e o custo estimado por país. Não muda nada.\n\nCom uma API key restrita a alguns números, a estimativa conta só os contatos do público que têm conversa nesses números."
          },
          "response": []
        },
        {
          "id": "c2707773-cef0-550b-a684-c51dc99f2ff4",
          "name": "Lançar campanha",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"scheduledAt\": \"2026-11-27T09:00:00-03:00\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/broadcasts/:id/launch",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "broadcasts",
                ":id",
                "launch"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{broadcastId}}"
                }
              ]
            },
            "description": "Sem `scheduledAt` (ou com `null`), a campanha sai agora.\n\nCongela o público e põe a campanha para enviar — agora, ou em `scheduledAt` (até um ano\nà frente). Mais de 60 segundos no futuro, a campanha fica `scheduled`; senão, começa a\nmontar a lista de destinatários na hora.\n\nNão aceita `Idempotency-Key`: um segundo lançamento responde `409`, porque a campanha\njá não é mais rascunho.\n\nCom uma API key restrita a alguns números, o público — salvo ou digitado como filtro — fica restrito aos contatos que têm conversa nesses números, e esse recorte é congelado no lançamento junto com o público. Uma campanha lançada por uma chave sem restrição vai para a base inteira."
          },
          "response": []
        },
        {
          "id": "4431efe9-ab4b-507a-a8b8-27dec1d446cc",
          "name": "Enviar teste da campanha",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"to\": \"5541987111527\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/broadcasts/:id/test",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "broadcasts",
                ":id",
                "test"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{broadcastId}}"
                }
              ]
            },
            "description": "Manda o template da campanha para um número, na hora, fora da fila e das métricas. As\nvariáveis vêm do contato `contactId`, se você mandar; senão, dos valores reserva\n(`fallback`). A campanha precisa estar completa.\n\nCom uma API key restrita a alguns números, um `contactId` sem conversa nesses números responde `404`."
          },
          "response": []
        },
        {
          "id": "21f3fe42-1e49-5b3d-a3e5-025d54ee9e21",
          "name": "Pausar campanha",
          "request": {
            "method": "POST",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/broadcasts/:id/pause",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "broadcasts",
                ":id",
                "pause"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{broadcastId}}"
                }
              ]
            },
            "description": ""
          },
          "response": []
        },
        {
          "id": "c179f43f-1947-5175-a4b6-bc3062ac8dec",
          "name": "Retomar campanha",
          "request": {
            "method": "POST",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/broadcasts/:id/resume",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "broadcasts",
                ":id",
                "resume"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{broadcastId}}"
                }
              ]
            },
            "description": ""
          },
          "response": []
        },
        {
          "id": "3f549e0f-6a07-5f06-aa23-48b353a72479",
          "name": "Cancelar campanha",
          "request": {
            "method": "POST",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/broadcasts/:id/cancel",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "broadcasts",
                ":id",
                "cancel"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{broadcastId}}"
                }
              ]
            },
            "description": "Para a campanha de vez. Quem ainda não recebeu fica como pulado, com o motivo `canceled`."
          },
          "response": []
        },
        {
          "id": "3d1c2915-2f95-5692-a7fb-b640402a9a61",
          "name": "Duplicar campanha",
          "request": {
            "method": "POST",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/broadcasts/:id/duplicate",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "broadcasts",
                ":id",
                "duplicate"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{broadcastId}}"
                }
              ]
            },
            "description": "Um rascunho novo com a mesma configuração, sem o agendamento."
          },
          "response": []
        },
        {
          "id": "29ea2c9b-5519-5e8d-a3e9-65969dc53c39",
          "name": "Arquivar campanha",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"archived\": true\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/broadcasts/:id/archive",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "broadcasts",
                ":id",
                "archive"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{broadcastId}}"
                }
              ]
            },
            "description": "Tira a campanha da lista principal (ou devolve, com `archived: false`). Uma campanha em andamento precisa ser cancelada ou terminar antes."
          },
          "response": []
        },
        {
          "id": "754b6cf4-5e99-5477-a824-57cc50118797",
          "name": "Reenviar destinatários sem resposta",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"confirm\": true\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/broadcasts/:id/resend-unknown",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "broadcasts",
                ":id",
                "resend-unknown"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{broadcastId}}"
                }
              ]
            },
            "description": "Destinatários `unknown` são envios em que a Meta nunca respondeu. Eles não são\nrepetidos sozinhos: a pessoa pode já ter recebido. Esta chamada os devolve à fila — por\nisso exige `confirm: true`. Uma campanha concluída volta a `running`."
          },
          "response": []
        },
        {
          "id": "78343485-489d-5b84-a772-8422ece78123",
          "name": "Métricas da campanha",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/broadcasts/:id/stats",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "broadcasts",
                ":id",
                "stats"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{broadcastId}}"
                }
              ]
            },
            "description": "Contadores, taxas, cliques por botão, falhas agrupadas, custo por país, latência de\nentrega e leitura, e a qualidade do número e do template antes e agora. As taxas de\nleitura, clique, resposta e opt-out são sobre as entregues."
          },
          "response": []
        },
        {
          "id": "1b1ce8f0-515a-5ea5-adb1-b6c3d0513d53",
          "name": "Série temporal da campanha",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/broadcasts/:id/timeseries",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "broadcasts",
                ":id",
                "timeseries"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{broadcastId}}"
                }
              ]
            },
            "description": "Envios, entregas, leituras, cliques, falhas e respostas por faixa de 15 minutos — ou de 1 hora, quando a campanha passa de dois dias."
          },
          "response": []
        },
        {
          "id": "b81d3287-2b90-5921-ab91-8d878c65acb6",
          "name": "Listar destinatários",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/broadcasts/:id/recipients",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "broadcasts",
                ":id",
                "recipients"
              ],
              "query": [
                {
                  "key": "limit",
                  "value": "50",
                  "disabled": true,
                  "description": "Itens por página."
                },
                {
                  "key": "offset",
                  "value": "0",
                  "disabled": true,
                  "description": "Quantos itens pular. É com ele que se pagina."
                },
                {
                  "key": "status",
                  "value": "pending",
                  "disabled": true
                },
                {
                  "key": "errorClass",
                  "value": "texto",
                  "disabled": true
                },
                {
                  "key": "clickedButton",
                  "value": "0",
                  "disabled": true
                },
                {
                  "key": "clicked",
                  "value": "true",
                  "disabled": true
                },
                {
                  "key": "replied",
                  "value": "true",
                  "disabled": true
                },
                {
                  "key": "optedOut",
                  "value": "true",
                  "disabled": true
                },
                {
                  "key": "q",
                  "value": "texto",
                  "disabled": true
                }
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{broadcastId}}"
                }
              ]
            },
            "description": ""
          },
          "response": []
        },
        {
          "id": "4367edbc-f9ad-510a-a080-d1f2fc54fd2f",
          "name": "Exportar destinatários em CSV",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/broadcasts/:id/export",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "broadcasts",
                ":id",
                "export"
              ],
              "query": [
                {
                  "key": "status",
                  "value": "pending",
                  "disabled": true
                },
                {
                  "key": "errorClass",
                  "value": "texto",
                  "disabled": true
                },
                {
                  "key": "clickedButton",
                  "value": "0",
                  "disabled": true
                },
                {
                  "key": "clicked",
                  "value": "true",
                  "disabled": true
                },
                {
                  "key": "replied",
                  "value": "true",
                  "disabled": true
                },
                {
                  "key": "optedOut",
                  "value": "true",
                  "disabled": true
                },
                {
                  "key": "q",
                  "value": "texto",
                  "disabled": true
                }
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{broadcastId}}"
                }
              ]
            },
            "description": "Os destinatários, com os mesmos filtros da listagem e sem paginação, num CSV com BOM UTF-8."
          },
          "response": []
        }
      ]
    },
    {
      "id": "2fa337f6-d334-575a-a9a5-c11e2c771aef",
      "name": "Fluxos",
      "description": "Fluxos são as automações visuais do painel. Pela API, você **dispara** um fluxo que\ntenha o gatilho \"API\" para um contato, e lista os fluxos para descobrir o id. Montar e\neditar o fluxo é tarefa do editor do painel.\n\nUm site conectado também inicia fluxos: ele reporta os seus eventos em `POST /site-events`,\ne cada fluxo com o gatilho de evento do site que escuta aquele nome recebe o evento.",
      "item": [
        {
          "id": "b22d152e-672c-555e-a82b-92f2b521293a",
          "name": "Listar fluxos",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "if (pm.response.code === 200 && !pm.collectionVariables.get('flowId')) {",
                  "  const json = pm.response.json();",
                  "  const first = json && Array.isArray(json.data) && json.data[0];",
                  "  if (first && first.id) pm.collectionVariables.set('flowId', first.id);",
                  "}"
                ]
              }
            }
          ],
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/flows",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "flows"
              ],
              "query": [
                {
                  "key": "limit",
                  "value": "50",
                  "disabled": true,
                  "description": "Itens por página."
                },
                {
                  "key": "offset",
                  "value": "0",
                  "disabled": true,
                  "description": "Quantos itens pular. É com ele que se pagina."
                },
                {
                  "key": "status",
                  "value": "draft",
                  "disabled": true
                },
                {
                  "key": "q",
                  "value": "texto",
                  "disabled": true,
                  "description": "Busca no nome."
                }
              ]
            },
            "description": "Os fluxos da conta, do editado mais recentemente ao mais antigo. Sem `status`, os\narquivados ficam de fora. Uma API key restrita a alguns números recebe `403`: gerenciar\nfluxos é da conta inteira — só o disparo aceita chave restrita."
          },
          "response": []
        },
        {
          "id": "a1909e5b-e4d0-5da5-adbd-7e7d291a9116",
          "name": "Consultar um fluxo",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/flows/:id",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "flows",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{flowId}}"
                }
              ]
            },
            "description": "O fluxo com o rascunho em edição (`draft`) e a lista de versões publicadas. O rascunho\né a cópia de trabalho do editor, não o que está rodando."
          },
          "response": []
        },
        {
          "id": "42ec803f-938f-5272-ad4a-8ab5889e9551",
          "name": "Disparar um fluxo",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}",
                "disabled": true,
                "description": "Identificador da operação. Repetir com o mesmo valor em 24 horas devolve a execução já iniciada."
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"contact\": {\n    \"phone\": \"+5541987111527\"\n  },\n  \"data\": {\n    \"pedido\": \"1042\",\n    \"valor\": \"R$ 189,90\"\n  }\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/flows/:id/trigger",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "flows",
                ":id",
                "trigger"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{flowId}}"
                }
              ]
            },
            "description": "Inicia uma execução do fluxo para um contato. O fluxo precisa estar **ativo e\npublicado**, e a versão publicada precisa ter um gatilho do tipo API.\n\nIdentifique o contato por `contact.id` ou por `contact.phone` — com o telefone, um\ncontato que não existe é criado. O que vier em `data` fica disponível no fluxo como\n`{{trigger.<caminho>}}` — dados aninhados inclusive (`{{trigger.cliente.nome}}`,\n`{{trigger.itens[0].nome}}`), com formatações como `:money` e `:date`. O número que\nenvia é `phoneNumberId`, ou o configurado no\ngatilho, ou o número ativo mais antigo da conta.\n\nA resposta é `202` com o `runId`; as mensagens saem em seguida, fora da requisição.\n`runId` pode vir `null` sem ser erro: o gatilho não leva a nenhum passo, ou o mesmo\ncontato começou este fluxo há pouco (o intervalo mínimo entre execuções). Começar uma\nexecução cancela as outras em andamento do mesmo contato naquele número.\n\n**Idempotência.** Com `Idempotency-Key`, repetir a chamada em até 24 horas devolve\n`200` com o mesmo `runId` e `replayed: true`, sem iniciar outra execução. Diferente de\n`POST /messages`: aqui o corpo **não** é comparado, e uma chamada que falhou não guarda a\nchave — a repetição tenta de novo."
          },
          "response": []
        },
        {
          "id": "88552838-a0e9-517f-a9c7-47e9c33efcca",
          "name": "Reportar eventos do site",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}",
                "disabled": true,
                "description": "Identificador da operação, escolhido por você — de 8 a 128 caracteres entre letras,\ndígitos, `_`, `-`, `.` e `:`. Repetir a chamada com o mesmo valor e o mesmo corpo\ndevolve a primeira resposta em vez de executar de novo. Vale por 24 horas, por conta."
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"events\": [\n    {\n      \"id\": \"9b2f6c1e-4d7a-4f0e-9a51-2f8c3d6e7a10\",\n      \"name\": \"wc.order.paid\",\n      \"occurred_at\": \"2026-09-24T14:32:05-03:00\",\n      \"site_url\": \"https://loja.example.com\",\n      \"contact\": {\n        \"ref\": {\n          \"kind\": \"wc_customer\",\n          \"id\": \"42\"\n        },\n        \"phone\": \"+5511987654321\",\n        \"country\": \"BR\",\n        \"first_name\": \"Ana\",\n        \"email\": \"ana@example.com\",\n        \"tags\": [\n          \"Cliente WooCommerce\"\n        ]\n      },\n      \"data\": {\n        \"order\": {\n          \"id\": 1042,\n          \"number\": \"1042\",\n          \"total\": \"189.90\",\n          \"status\": \"processing\"\n        }\n      }\n    }\n  ]\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/site-events",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "site-events"
              ]
            },
            "description": "É por aqui que um site conectado conta o que aconteceu nele — um pedido pago, um\ncadastro, um carrinho abandonado —, até 100 eventos por chamada. É o que o plugin do\nWordPress chama, e qualquer plataforma própria com a API key de um site conectado pode\nchamar também.\n\nO site não precisa saber quais fluxos existem: ele reporta o evento pelo nome, e todo fluxo\nativo e publicado com o gatilho de evento do site que escuta esse nome o recebe (no máximo\n20 fluxos por evento, pela prioridade), assim como as execuções que estão esperando por\nele. No fluxo, o que vier em `data` fica disponível como `{{trigger.<caminho>}}` —\n`{{trigger.order.total}}` —, ao lado de `trigger.$event` (`id`, `name`, `occurred_at`) e\n`trigger.$site` (`id`, `url`, `name`).\n\n**Nomes.** `<origem>.<objeto>.<acontecimento>`, em minúsculas, de 2 a 4 segmentos e até\n80 caracteres: `wc.order.paid`, `wp.user.registered`. As origens `wp`, `wc`, `wcs`,\n`form` e `fcrc` são as do catálogo do plugin; os eventos da sua própria integração vão em\n`custom` — `custom.assinatura.renovada`.\n\n**Contato.** O bloco `contact` passa pela mesma sincronização de `POST /contacts/sync`,\ncom os campos em snake_case e com os gatilhos ligados: um contato novo ou uma tag\nadicionada iniciam os fluxos de sempre. Sem um contato válido, nenhum fluxo começa — mas\num bloco `contact` inválido não recusa o evento, que fica registrado com o motivo.\n\n**Resposta.** `202` quer dizer registrado e enfileirado: nenhum fluxo roda dentro da\nrequisição. Cada evento responde por si — um inválido volta em `rejected`, com a posição e\no motivo, sem derrubar o lote; um `id` que o site já reportou conta em `duplicates` e não\nmuda nada. A entrega é \"pelo menos uma vez\": reenviar é seguro. Cada evento tem até 64 KB\nentre `data` e `contact`.\n\nEsta rota não responde `402`: com a conta bloqueada, os eventos são aceitos e registrados\nsem rodar fluxos, para que o site não acumule reenvios.\n\n**Idempotência.** Com o header `Idempotency-Key`, uma repetição da mesma chamada devolve\na primeira resposta, com `Idempotent-Replayed: true`. A mesma chave com outro corpo é\nrecusada com `422 idempotency_key_reused`; enquanto a primeira requisição ainda roda, a\nrepetição recebe `409 idempotency_in_progress`.\n\nSó a API key de um site conectado reporta eventos — ela vem com a permissão\n`events:write`. Uma API key comum recebe `404 site_not_found`."
          },
          "response": []
        },
        {
          "id": "b7c1f0e2-6a3d-5e41-a9f2-3c4d5e6f7a80",
          "name": "Chamar o webhook de um gatilho",
          "request": {
            "auth": {
              "type": "noauth"
            },
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"order\": {\n    \"id\": 1042,\n    \"total\": \"189.90\"\n  },\n  \"customer\": {\n    \"first_name\": \"Ana\",\n    \"phone\": \"+5541987111527\"\n  }\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/hooks/:token",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "hooks",
                ":token"
              ],
              "variable": [
                {
                  "key": "token",
                  "value": "{{hookToken}}",
                  "description": "O token da URL que o nó de gatilho \"Webhook\" mostra no painel."
                }
              ]
            },
            "description": "A URL de um gatilho **Webhook** de fluxo: uma loja (ou qualquer plataforma) chama com o próprio payload, e o fluxo começa.\n\nPúblico — o token no caminho é a credencial. Aceita `POST`, `PUT` e `PATCH`; um `GET` responde `{ \"ok\": true }` para as plataformas que conferem a URL antes de salvar. Se o gatilho tiver HMAC configurado, envie a assinatura no header que ele pede."
          },
          "response": []
        }
      ]
    },
    {
      "id": "d749d834-8530-56a0-a220-84c419bd8952",
      "name": "Inbox",
      "description": "A caixa de entrada compartilhada: conversas, mensagens e respostas, no mesmo lugar em\nque a equipe atende pelo painel. Serve para ligar um helpdesk ou um bot externo. Uma API\nkey restrita a alguns números só vê as conversas desses números.",
      "item": [
        {
          "id": "b165aaf7-d66a-5d1b-a6b6-ac51db988298",
          "name": "Eventos da inbox em tempo real",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/inbox/stream",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "inbox",
                "stream"
              ]
            },
            "description": "Um stream Server-Sent Events com o que acontece na inbox: mensagem nova, status de\nmensagem, conversa atualizada, alguém digitando. Os eventos avisam **o quê** mudou, sem o\nconteúdo — busque a conversa ou as mensagens em seguida.\n\nO stream começa com `event: ready` e manda um comentário `: ping` a cada 25 segundos.\n**Não há reenvio**: o `id` de cada evento é um contador da conexão, e `Last-Event-ID`\nnão recupera nada. A cada (re)conexão, releia o que importa. O `EventSource` do navegador\nnão manda o header `Authorization` — use um cliente que mande. No máximo 5 streams\nabertos por API key."
          },
          "response": []
        },
        {
          "id": "af7cb351-8216-5247-ac94-0329a123972f",
          "name": "Listar conversas",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "if (pm.response.code === 200 && !pm.collectionVariables.get('conversationId')) {",
                  "  const json = pm.response.json();",
                  "  const first = json && Array.isArray(json.data) && json.data[0];",
                  "  if (first && first.id) pm.collectionVariables.set('conversationId', first.id);",
                  "}"
                ]
              }
            }
          ],
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/inbox/conversations",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "inbox",
                "conversations"
              ],
              "query": [
                {
                  "key": "folder",
                  "value": "open",
                  "disabled": true
                },
                {
                  "key": "phoneNumberId",
                  "value": "texto",
                  "disabled": true
                },
                {
                  "key": "tagId",
                  "value": "texto",
                  "disabled": true
                },
                {
                  "key": "assignedUserId",
                  "value": "texto",
                  "disabled": true
                },
                {
                  "key": "unread",
                  "value": "true",
                  "disabled": true,
                  "description": "`true`: só conversas com mensagens não lidas."
                },
                {
                  "key": "window",
                  "value": "open",
                  "disabled": true,
                  "description": "`open`: a janela de 24 horas está aberta e dá para responder texto livre."
                },
                {
                  "key": "q",
                  "value": "texto",
                  "disabled": true,
                  "description": "Busca por nome, e-mail ou telefone."
                },
                {
                  "key": "cursor",
                  "value": "texto",
                  "disabled": true
                },
                {
                  "key": "limit",
                  "value": "30",
                  "disabled": true
                }
              ]
            },
            "description": "As conversas, da mais recente à mais antiga, paginadas por cursor: mande o\n`nextCursor` da resposta em `cursor` para a próxima página. `folder` escolhe a pasta\ndo painel — `mine` é sempre vazia para uma API key, que não é uma pessoa da equipe."
          },
          "response": []
        },
        {
          "id": "cb92060f-0594-50f6-a705-5107fd2f2f6a",
          "name": "Contagem das pastas",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/inbox/counts",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "inbox",
                "counts"
              ]
            },
            "description": ""
          },
          "response": []
        },
        {
          "id": "5015a992-3230-5347-a1d1-fa0db035d242",
          "name": "Consultar uma conversa",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/inbox/conversations/:id",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "inbox",
                "conversations",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{conversationId}}"
                }
              ]
            },
            "description": "A conversa com o contato completo e as últimas campanhas que ele recebeu."
          },
          "response": []
        },
        {
          "id": "19beccfd-3ead-5c3c-a4bd-ebca6a7df692",
          "name": "Atualizar uma conversa",
          "request": {
            "method": "PATCH",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"status\": \"closed\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/inbox/conversations/:id",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "inbox",
                "conversations",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{conversationId}}"
                }
              ]
            },
            "description": "Muda o status (fechar, reabrir, deixar pendente, adiar até `snoozedUntil`), atribui a\nalguém da equipe ou pausa as automações por 30 dias. Cada mudança vira uma linha na\nconversa. Fechar e atribuir disparam `conversation.closed` e `conversation.assigned`."
          },
          "response": []
        },
        {
          "id": "075a2922-e35f-5bda-aadf-d1958462cb4a",
          "name": "Mensagens de uma conversa",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/inbox/conversations/:id/messages",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "inbox",
                "conversations",
                ":id",
                "messages"
              ],
              "query": [
                {
                  "key": "before",
                  "value": "texto",
                  "disabled": true
                },
                {
                  "key": "limit",
                  "value": "50",
                  "disabled": true
                }
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{conversationId}}"
                }
              ]
            },
            "description": "Da mais recente à mais antiga, com notas internas e eventos (atribuição, fechamento)\nmisturados às mensagens. Para páginas anteriores, mande o `nextCursor` em `before`."
          },
          "response": []
        },
        {
          "id": "00645fdd-f835-5d16-a990-146a3ebcda60",
          "name": "Responder com texto",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"kind\": \"text\",\n  \"text\": \"Oi, Ana! Seu pedido saiu para entrega.\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/inbox/conversations/:id/messages",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "inbox",
                "conversations",
                ":id",
                "messages"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{conversationId}}"
                }
              ]
            },
            "description": "Manda uma mensagem pelo número da conversa, escolhida por `kind`:\n\n| `kind` | O quê |\n|---|---|\n| `text` | Texto livre. Só com a janela de 24 horas aberta |\n| `media` | Um arquivo já enviado em `POST /inbox/conversations/{id}/media`. Só com a janela aberta |\n| `template` | Um template aprovado. Reabre a conversa a qualquer momento |\n| `note` | Nota interna: fica na conversa, nunca vai para o WhatsApp |\n\nFora da janela, `text` e `media` são recusados **antes** do envio com\n`422 window_closed` e o `windowExpiresAt`. A resposta reabre uma conversa fechada ou\nadiada e pausa as automações por um tempo, como quando alguém da equipe responde."
          },
          "response": []
        },
        {
          "id": "1a2a9a90-8647-5e20-a41d-c981ca6c8b5b",
          "name": "Responder com template",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"kind\": \"template\",\n  \"templateId\": \"{{templateId}}\",\n  \"variables\": {}\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/inbox/conversations/:id/messages",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "inbox",
                "conversations",
                ":id",
                "messages"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{conversationId}}"
                }
              ]
            },
            "description": "Fora da janela de 24 h só template sai. `templateId` é o id em `GET /templates`.\n\nManda uma mensagem pelo número da conversa, escolhida por `kind`:\n\n| `kind` | O quê |\n|---|---|\n| `text` | Texto livre. Só com a janela de 24 horas aberta |\n| `media` | Um arquivo já enviado em `POST /inbox/conversations/{id}/media`. Só com a janela aberta |\n| `template` | Um template aprovado. Reabre a conversa a qualquer momento |\n| `note` | Nota interna: fica na conversa, nunca vai para o WhatsApp |\n\nFora da janela, `text` e `media` são recusados **antes** do envio com\n`422 window_closed` e o `windowExpiresAt`. A resposta reabre uma conversa fechada ou\nadiada e pausa as automações por um tempo, como quando alguém da equipe responde."
          },
          "response": []
        },
        {
          "id": "0b903012-d6e3-565f-ab34-41975371381f",
          "name": "Deixar nota interna",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"kind\": \"note\",\n  \"text\": \"Cliente pediu troca, aguardando o estoque.\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/inbox/conversations/:id/messages",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "inbox",
                "conversations",
                ":id",
                "messages"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{conversationId}}"
                }
              ]
            },
            "description": "Fica só na conversa, para a equipe — não vai para o WhatsApp.\n\nManda uma mensagem pelo número da conversa, escolhida por `kind`:\n\n| `kind` | O quê |\n|---|---|\n| `text` | Texto livre. Só com a janela de 24 horas aberta |\n| `media` | Um arquivo já enviado em `POST /inbox/conversations/{id}/media`. Só com a janela aberta |\n| `template` | Um template aprovado. Reabre a conversa a qualquer momento |\n| `note` | Nota interna: fica na conversa, nunca vai para o WhatsApp |\n\nFora da janela, `text` e `media` são recusados **antes** do envio com\n`422 window_closed` e o `windowExpiresAt`. A resposta reabre uma conversa fechada ou\nadiada e pausa as automações por um tempo, como quando alguém da equipe responde."
          },
          "response": []
        },
        {
          "id": "3b676f89-9b6a-5332-a653-9f69462effd6",
          "name": "Marcar conversa como lida",
          "request": {
            "method": "POST",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/inbox/conversations/:id/read",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "inbox",
                "conversations",
                ":id",
                "read"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{conversationId}}"
                }
              ]
            },
            "description": "Zera o contador de não lidas e, se a conta envia confirmação de leitura, marca a última mensagem do cliente como lida no WhatsApp."
          },
          "response": []
        },
        {
          "id": "c4b933ee-fc88-50a9-afe5-a137d007e6ef",
          "name": "Mostrar indicador de digitação",
          "request": {
            "method": "POST",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/inbox/conversations/:id/typing",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "inbox",
                "conversations",
                ":id",
                "typing"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{conversationId}}"
                }
              ]
            },
            "description": "Mostra o indicador de digitação para o cliente, com a janela aberta e as confirmações de leitura ligadas. No máximo uma vez a cada 20 segundos por conversa."
          },
          "response": []
        },
        {
          "id": "4afcfd34-0c50-52b1-a5e4-f7e25ba95803",
          "name": "Subir arquivo para uma conversa",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "{{mediaContentType}}",
                "description": "application/octet-stream"
              },
              {
                "key": "X-File-Name",
                "value": "",
                "disabled": true,
                "description": "Nome do arquivo, codificado como URI."
              }
            ],
            "body": {
              "mode": "file",
              "file": {}
            },
            "url": {
              "raw": "{{baseUrl}}/inbox/conversations/:id/media",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "inbox",
                "conversations",
                ":id",
                "media"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{conversationId}}"
                }
              ]
            },
            "description": "Envie os bytes do arquivo no corpo (não é multipart), com o nome em `X-File-Name`. O\ntipo é detectado pelo conteúdo: imagem (JPEG, PNG), figurinha (WebP), vídeo (MP4, 3GP),\náudio, PDF, documentos do Office e texto. Limites: imagem 5 MB, vídeo e áudio 16 MB,\ndocumento 100 MB, figurinha 500 KB. Use o `id` devolvido como `assetId` numa resposta\n`kind: media`."
          },
          "response": []
        },
        {
          "id": "897e6675-7728-5bd1-ae3f-b1da2cdfc06e",
          "name": "Link de um arquivo da inbox",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/inbox/media/:id/url",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "inbox",
                "media",
                ":id",
                "url"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{inboxMediaId}}"
                }
              ]
            },
            "description": "Um link temporário para baixar um arquivo de mensagem, recebido ou enviado. Vale por 5 minutos; peça outro quando expirar."
          },
          "response": []
        },
        {
          "id": "b056d03a-b17f-5d3a-aef9-933602774f7a",
          "name": "Pessoas da equipe",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/inbox/agents",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "inbox",
                "agents"
              ],
              "query": [
                {
                  "key": "phoneNumberId",
                  "value": "texto",
                  "disabled": true
                }
              ]
            },
            "description": "Quem pode receber conversas — é daqui que sai o `assignedUserId`. Com `phoneNumberId`, só quem atende esse número.\n\nUma API key restrita a alguns números recebe `403`: a equipe é da conta inteira."
          },
          "response": []
        }
      ]
    },
    {
      "id": "4bace955-9b10-51aa-afda-b2ad60c4032b",
      "name": "Webhooks",
      "description": "Cadastro dos endpoints que recebem os eventos das suas contas, mais o log de\nentregas e as ferramentas de teste e reenvio.\n\nCada entrega é assinada com `HMAC-SHA256(segredo, \"{timestamp}.{corpo bruto}\")`\nno header `X-Joinotify-Signature-256`. Falhas são reentregues em 60s, 5min,\n30min, 2h e 6h.\n\nO passo a passo completo está no guia de [Webhooks](/webhooks).",
      "item": [
        {
          "id": "8eaef90a-a614-5932-a74d-5aeddcf21d90",
          "name": "Listar endpoints",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "if (pm.response.code === 200 && !pm.collectionVariables.get('webhookEndpointId')) {",
                  "  const json = pm.response.json();",
                  "  const first = json && Array.isArray(json.data) && json.data[0];",
                  "  if (first && first.id) pm.collectionVariables.set('webhookEndpointId', first.id);",
                  "}"
                ]
              }
            }
          ],
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/webhook-endpoints",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "webhook-endpoints"
              ]
            },
            "description": "Lista os endpoints cadastrados. O segredo de assinatura não é devolvido —\nuse `GET /webhook-endpoints/{id}/secret`.\n\n`failureCount` e `disabledAt` mostram endpoints em apuros: 50 falhas seguidas\ndesativam o endpoint automaticamente."
          },
          "response": []
        },
        {
          "id": "cc17fe1a-e644-508b-aff9-32fb98516ba8",
          "name": "Criar endpoint",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const json = pm.response.json();",
                  "const value = json && json.data && json.data.id;",
                  "if (pm.response.code < 300 && value) pm.collectionVariables.set('webhookEndpointId', value);"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"name\": \"producao\",\n  \"url\": \"https://seu-servidor.com/webhooks/joinotify\",\n  \"events\": [\n    \"messages\"\n  ]\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/webhook-endpoints",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "webhook-endpoints"
              ]
            },
            "description": "Cadastra uma URL para receber eventos. O segredo de assinatura aparece\n**somente nesta resposta**.\n\nDeixar `events` como lista vazia assina **todos** os eventos. Os filtros\n`wabaId` e `phoneNumberId` restringem a entrega a uma conta ou número.\n\nEm produção a URL precisa ser HTTPS e pública: recusamos `http://` e hosts\nprivados como `localhost`, `127.*`, `10.*`, `192.168.*` e `*.internal`."
          },
          "response": []
        },
        {
          "id": "08df59fb-47ae-5d1a-adf9-afbed1baab2f",
          "name": "Atualizar endpoint",
          "request": {
            "method": "PATCH",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"url\": \"https://seu-servidor.com/webhooks/joinotify\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/webhook-endpoints/:id",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "webhook-endpoints",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{webhookEndpointId}}",
                  "description": "ID do endpoint de webhook."
                }
              ]
            },
            "description": "Atualiza os campos informados. Os omitidos ficam como estão.\n\nReativar um endpoint desativado (`active: true`) zera o contador de falhas e\nlimpa o `disabledAt`."
          },
          "response": []
        },
        {
          "id": "fc02b3ca-7d7a-5fae-ae10-38a73ffb883a",
          "name": "Remover endpoint",
          "request": {
            "method": "DELETE",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/webhook-endpoints/:id",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "webhook-endpoints",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{webhookEndpointId}}",
                  "description": "ID do endpoint de webhook."
                }
              ]
            },
            "description": "Remove o endpoint. Entregas pendentes para ele são descartadas.\n\nSe a intenção é apenas pausar, prefira `PATCH` com `active: false` — assim o\nhistórico e o segredo são preservados."
          },
          "response": []
        },
        {
          "id": "a1ce2d45-1ccc-5e8a-a31f-d294401e4978",
          "name": "Revelar segredo",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/webhook-endpoints/:id/secret",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "webhook-endpoints",
                ":id",
                "secret"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{webhookEndpointId}}",
                  "description": "ID do endpoint de webhook."
                }
              ]
            },
            "description": "Devolve o segredo de assinatura em texto claro. Diferente das chaves de API,\no segredo de webhook pode ser consultado depois da criação."
          },
          "response": []
        },
        {
          "id": "3e6ac5f5-ad3d-5674-a87b-2116e43d0b43",
          "name": "Rotacionar segredo",
          "request": {
            "method": "POST",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/webhook-endpoints/:id/rotate-secret",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "webhook-endpoints",
                ":id",
                "rotate-secret"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{webhookEndpointId}}",
                  "description": "ID do endpoint de webhook."
                }
              ]
            },
            "description": "Gera um segredo novo. A troca é **imediata**: a próxima entrega já vai\nassinada com ele.\n\nNão há período de convivência entre os dois segredos. Publique o novo no seu\nservidor antes de rotacionar, ou aceite que algumas entregas falhem e sejam\nreentregues depois."
          },
          "response": []
        },
        {
          "id": "6fdc9561-782d-575c-a2ee-9948b2d13e75",
          "name": "Testar endpoint",
          "request": {
            "method": "POST",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/webhook-endpoints/:id/test",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "webhook-endpoints",
                ":id",
                "test"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{webhookEndpointId}}",
                  "description": "ID do endpoint de webhook."
                }
              ]
            },
            "description": "Dispara um evento sintético e entrega **na hora**, sem passar pela fila. A\nresposta traz o status HTTP e o corpo devolvidos pelo seu servidor — é a forma\nmais rápida de conferir se a validação de assinatura está correta.\n\nO payload de teste é um evento `messages` com o campo `joinotify_test: true`."
          },
          "response": []
        },
        {
          "id": "c73b7df5-155c-54df-a1cb-c612f1748f41",
          "name": "Catálogo de eventos",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/webhook-endpoints/events",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "webhook-endpoints",
                "events"
              ]
            },
            "description": "Lista os nomes de evento que podem ser assinados no campo `events` de um\nendpoint."
          },
          "response": []
        },
        {
          "id": "b627e13f-bf9f-5a75-aa4b-c7a96e0507d9",
          "name": "Log de entregas",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/webhook-endpoints/deliveries",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "webhook-endpoints",
                "deliveries"
              ],
              "query": [
                {
                  "key": "endpointId",
                  "value": "texto",
                  "disabled": true
                },
                {
                  "key": "status",
                  "value": "pending",
                  "disabled": true
                },
                {
                  "key": "limit",
                  "value": "50",
                  "disabled": true
                }
              ]
            },
            "description": "Histórico das entregas, com o status HTTP e o corpo devolvidos pelo seu\nservidor. É por aqui que se investiga por que um evento não chegou.\n\nFiltre por `status: failed` para ver o que esgotou as seis tentativas."
          },
          "response": []
        },
        {
          "id": "8b6b59e5-aa61-5c32-ac72-c903e6fdd96a",
          "name": "Reenviar entrega",
          "request": {
            "method": "POST",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/webhook-endpoints/deliveries/:deliveryId/redeliver",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "webhook-endpoints",
                "deliveries",
                ":deliveryId",
                "redeliver"
              ],
              "variable": [
                {
                  "key": "deliveryId",
                  "value": "{{deliveryId}}"
                }
              ]
            },
            "description": "Coloca o mesmo evento de volta na fila.\n\nO reenvio cria uma entrega **nova** em vez de reciclar a antiga, então o\nhistórico da falha original é preservado."
          },
          "response": []
        }
      ]
    },
    {
      "id": "ec76ebd5-ab1c-51ce-adb0-ee428d0b3c7a",
      "name": "Eventos",
      "description": "Consulta ao histórico bruto de eventos que a Meta enviou para as suas contas.\n\nÚtil para depurar uma integração antes de ter um endpoint de webhook no ar, ou\npara reprocessar algo que o seu servidor perdeu.",
      "item": [
        {
          "id": "fd356afe-45b2-5033-af77-deb4eddca267",
          "name": "Listar eventos recebidos",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/events",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "events"
              ],
              "query": [
                {
                  "key": "field",
                  "value": "texto",
                  "disabled": true,
                  "description": "Nome do evento, ex. `messages`."
                },
                {
                  "key": "phoneNumberId",
                  "value": "texto",
                  "disabled": true
                },
                {
                  "key": "limit",
                  "value": "50",
                  "disabled": true
                }
              ]
            },
            "description": "Histórico bruto dos eventos que a Meta enviou para as suas contas, do mais\nrecente para o mais antigo. O campo `payload` é o `change.value` original,\nsem alteração.\n\nServe para depurar uma integração antes de ter um endpoint de webhook no ar,\nou para reprocessar algo que o seu servidor perdeu."
          },
          "response": []
        }
      ]
    },
    {
      "id": "46f6d7e4-52b6-5c46-a261-5858978025ec",
      "name": "Chaves de API",
      "description": "Criação, listagem e revogação das chaves que autenticam suas requisições.\n\nO segredo completo é mostrado **uma única vez**, na resposta da criação —\nguardamos apenas o hash. A revogação tem efeito imediato.",
      "item": [
        {
          "id": "8fcccb45-5a29-57f5-a2fb-4ed8d622e333",
          "name": "Trocar código de pareamento por chave",
          "request": {
            "auth": {
              "type": "noauth"
            },
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"code\": \"ABCD-1234\",\n  \"site\": \"https://loja.exemplo.com\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/keys/exchange",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "keys",
                "exchange"
              ]
            },
            "description": "O site apresenta o código emitido no painel e recebe uma API key própria. Chamada\nservidor-a-servidor, sem credencial prévia — o código é a credencial e vale uma vez.\n\nA chave sai ligada ao site (`siteId`) e com as permissões de um site conectado. Código\ninexistente, expirado, já usado, emitido para outro endereço ou corpo inválido recebem\na mesma resposta, `401 pairing_invalid`: de fora não dá para distinguir um caso do outro.\nLimite de 20 tentativas a cada 10 minutos por IP."
          },
          "response": []
        },
        {
          "id": "0cfa2417-2de7-56ca-a943-0aa0d68ccdb9",
          "name": "Trocar licença por chave do site",
          "request": {
            "auth": {
              "type": "noauth"
            },
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"licenseKey\": \"{{licenseKey}}\",\n  \"siteUrl\": \"https://loja.exemplo.com\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/sites/bootstrap",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "sites",
                "bootstrap"
              ]
            },
            "description": "O plugin se apresenta com a chave de licença e sai configurado: recebe uma API key\ne já a lista de números de origem.\n\nA licença **só faz o bootstrap** — ela nunca autentica um envio. A chave que ela\nemite é revogável sozinha, no painel.\n\nUma chave viva por site: reinstalar emite outra e derruba a anterior."
          },
          "response": []
        },
        {
          "id": "c6e9fb73-6e6b-5c9c-a07a-fdf4f5de16e7",
          "name": "Listar chaves",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "if (pm.response.code === 200 && !pm.collectionVariables.get('keyId')) {",
                  "  const json = pm.response.json();",
                  "  const first = json && Array.isArray(json.data) && json.data[0];",
                  "  if (first && first.id) pm.collectionVariables.set('keyId', first.id);",
                  "}"
                ]
              }
            }
          ],
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/keys",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "keys"
              ]
            },
            "description": "Lista as chaves da conta. Segredos **nunca** são devolvidos aqui — apenas o\nprefixo, que serve para identificar a chave.\n\nUse `lastUsedAt` para descobrir chaves esquecidas antes de revogá-las."
          },
          "response": []
        },
        {
          "id": "15ace8a2-8d3d-52d4-aa42-6ae4c850f3eb",
          "name": "Criar chave",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const json = pm.response.json();",
                  "const value = json && json.data && json.data.id;",
                  "if (pm.response.code < 300 && value) pm.collectionVariables.set('keyId', value);"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"name\": \"integracao-erp\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/keys",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "keys"
              ]
            },
            "description": "Cria uma chave nova. O segredo completo aparece **somente nesta resposta** —\nguardamos apenas o hash SHA-256.\n\nCrie uma chave por integração: quando uma vazar, você revoga só ela."
          },
          "response": []
        },
        {
          "id": "53ec033c-deb2-50a0-a0f2-9b1f579631f0",
          "name": "Revogar chave",
          "request": {
            "method": "DELETE",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/keys/:id",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "keys",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{keyId}}",
                  "description": "ID da chave, obtido em `GET /keys`."
                }
              ]
            },
            "description": "Revoga a chave imediatamente — a próxima requisição com ela recebe\n`401 authentication`.\n\nA operação é idempotente: revogar uma chave já revogada também devolve `200`."
          },
          "response": []
        }
      ]
    },
    {
      "id": "90876604-3338-5f2b-a12b-14679b4ef14d",
      "name": "Planos",
      "description": "Catálogo público de planos e a calculadora de preços — os dois sem credencial.",
      "item": [
        {
          "id": "5ed87416-fe9f-5d2a-a363-0ad26a4c55ba",
          "name": "Listar planos",
          "request": {
            "auth": {
              "type": "noauth"
            },
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/plans",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "plans"
              ]
            },
            "description": "Catálogo público — é o que a página de preços mostra. **Não exige credencial.**"
          },
          "response": []
        },
        {
          "id": "30e9e34a-e6b2-5b33-ab21-32d93fabeaa7",
          "name": "Cotar planos por quantidade de números",
          "request": {
            "auth": {
              "type": "noauth"
            },
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/plans/quote?numbers=3",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "plans",
                "quote"
              ],
              "query": [
                {
                  "key": "numbers",
                  "value": "3",
                  "description": "Quantos números do WhatsApp cotar."
                },
                {
                  "key": "currency",
                  "value": "usd",
                  "disabled": true,
                  "description": "Moeda ISO 4217 desejada (`brl`, `usd`, `eur`…). Um plano que não é vendido nela é cotado na moeda base."
                }
              ]
            },
            "description": "Preço de cada plano do catálogo público para uma quantidade de números do WhatsApp,\ne o recomendado: o mais barato por mês entre os que comportam essa quantidade. É a\ncalculadora da página de preços. **Não exige credencial** e aceita leitura de qualquer\norigem, sem cookies.\n\nPlanos fixos com `stackable` são cotados em cópias — `quantity: 2` é \"2 × Start\".\nCupom e período de teste dependem da conta e vêm sempre `null` aqui."
          },
          "response": []
        }
      ]
    },
    {
      "id": "aadf676e-914d-5e6b-a177-b799752d21b4",
      "name": "Faturamento",
      "description": "Assinatura, franquias e faturas — em leitura. Trocar de plano, cancelar e abrir o\ncheckout são decisões do dono da conta e acontecem no painel, não por API key.",
      "item": [
        {
          "id": "e7a66370-60d4-567e-a632-b6dd8c6b83e3",
          "name": "Assinatura e franquias",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/billing",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "billing"
              ]
            },
            "description": "Estado da assinatura, números cobráveis, consumo contra o teto do plano e as\nlicenças ativas, numa resposta só.\n\nTrocar de plano, cancelar e abrir o checkout exigem sessão do painel: são decisões\ndo dono da conta, e uma API key pertence à conta, não a uma pessoa."
          },
          "response": []
        },
        {
          "id": "b132092d-7bee-5779-a1f3-6a0fe0879767",
          "name": "Listar faturas",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/billing/invoices",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "billing",
                "invoices"
              ],
              "query": [
                {
                  "key": "limit",
                  "value": "50",
                  "disabled": true,
                  "description": "Itens por página."
                },
                {
                  "key": "offset",
                  "value": "0",
                  "disabled": true,
                  "description": "Quantos itens pular. É com ele que se pagina."
                }
              ]
            },
            "description": "Faturas espelhadas do Stripe, da mais recente para a mais antiga."
          },
          "response": []
        },
        {
          "id": "570e68a0-6401-56bf-a92a-c1e9b70d7970",
          "name": "Baixar a nota fiscal de servico",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/billing/invoices/:id/nfse",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "billing",
                "invoices",
                ":id",
                "nfse"
              ],
              "query": [
                {
                  "key": "kind",
                  "value": "pdf",
                  "disabled": true,
                  "description": "`pdf` (padrao) ou `xml`."
                }
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{invoiceId}}",
                  "description": "Id da fatura."
                }
              ]
            },
            "description": "Devolve um link curto para o arquivo da nota — um link, e nao os bytes, porque quem\nserve o arquivo e o bucket. Vale por poucos minutos e nao deve ser guardado."
          },
          "response": []
        },
        {
          "id": "4a4e4293-7f3d-5f8c-a125-51c06d977385",
          "name": "Listar licenças",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/billing/license",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "billing",
                "license"
              ]
            },
            "description": "Licenças MeuMouse.com ligadas à conta e quantos números cada uma cobre. As chaves\nnunca são devolvidas."
          },
          "response": []
        }
      ]
    },
    {
      "id": "ec54acfa-3ade-558e-a1c9-08c90704356b",
      "name": "Carteira",
      "description": "Saldo da carteira, extrato e o programa de indicação — em leitura. Pedir saque e\nalterar os dados de recebimento são decisões do dono da conta e acontecem no painel,\nnão por API key.",
      "item": [
        {
          "id": "ee68fc8c-f4d1-599c-a709-8f40c5fc9b4d",
          "name": "Saldo da carteira",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/wallet",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "wallet"
              ]
            },
            "description": "Os três saldos da carteira e a próxima liberação.\n\nOs três não se somam: `availableCents` é o que pode ser usado hoje;\n`pendingCents` é comissão ainda dentro da carência, que absorve um reembolso que\nchegue depois; `reservedCents` é dinheiro já comprometido com um saque em análise.\nCom `negative: true`, o saldo disponível está negativo e saques ficam bloqueados."
          },
          "response": []
        },
        {
          "id": "f63b26c4-6094-53c9-a722-3ee1e6bdd3e7",
          "name": "Extrato da carteira",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/wallet/entries",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "wallet",
                "entries"
              ],
              "query": [
                {
                  "key": "type",
                  "value": "texto",
                  "disabled": true,
                  "description": "Tipo do lançamento: `commission`, `commission_reversal`, `release`, `invoice_credit`, `invoice_credit_reversal`, `payout_reserve`, `payout_settle`, `payout_reversal`, `adjustment`…"
                },
                {
                  "key": "bucket",
                  "value": "available",
                  "disabled": true,
                  "description": "Qual saldo o lançamento movimenta."
                },
                {
                  "key": "from",
                  "value": "2026-12-01T12:00:00Z",
                  "disabled": true,
                  "description": "A partir de (ISO 8601)."
                },
                {
                  "key": "to",
                  "value": "2026-12-01T12:00:00Z",
                  "disabled": true,
                  "description": "Até (ISO 8601)."
                },
                {
                  "key": "limit",
                  "value": "25",
                  "disabled": true,
                  "description": "Itens por página."
                },
                {
                  "key": "offset",
                  "value": "0",
                  "disabled": true,
                  "description": "Quantos itens pular. É com ele que se pagina."
                }
              ]
            },
            "description": "Os lançamentos da carteira, do mais recente ao mais antigo. Cada um traz uma chave de\ntradução (`descriptionKey`) e os parâmetros dela em vez de um texto pronto, para que\no extrato possa ser lido em qualquer idioma."
          },
          "response": []
        },
        {
          "id": "2ca538d5-8a9b-51c3-ab83-c35a27ca1980",
          "name": "Programa de indicação",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/affiliate",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "affiliate"
              ]
            },
            "description": "A inscrição da conta no programa de indicação — o status, o código público, as\ncondições em vigor e a contagem de indicados por status. Para quem ainda não se\ninscreveu, `enrolled: false` e as condições oferecidas em `offer`.\n\nOs dados de recebimento vêm mascarados: o destino completo nunca sai da API."
          },
          "response": []
        },
        {
          "id": "c5c4c773-08b9-5770-a36b-af782fcfe84a",
          "name": "Listar indicados",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/affiliate/referrals",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "affiliate",
                "referrals"
              ],
              "query": [
                {
                  "key": "status",
                  "value": "pending",
                  "disabled": true
                },
                {
                  "key": "limit",
                  "value": "25",
                  "disabled": true,
                  "description": "Itens por página."
                },
                {
                  "key": "offset",
                  "value": "0",
                  "disabled": true,
                  "description": "Quantos itens pular. É com ele que se pagina."
                }
              ]
            },
            "description": "Quem foi indicado e quanto cada um já gerou de comissão. Sem e-mail nem telefone do\ncliente indicado — só o rótulo copiado na atribuição. Quando um indicado não gera\ncomissão, `disqualifiedReason` diz por quê."
          },
          "response": []
        }
      ]
    },
    {
      "id": "ea80b011-c9eb-5665-afab-d0bbecd6d984",
      "name": "Auditoria",
      "description": "Erros e alertas da sua conta do WhatsApp: o que a Meta recusou, o que caiu por\nqualidade do número, o que um template perdeu na revisão. É a trilha que explica\npor que uma mensagem não chegou.",
      "item": [
        {
          "id": "97e49570-ba9c-5901-aa78-5b2052f18be3",
          "name": "Erros e alertas da conta",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/audit",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "audit"
              ],
              "query": [
                {
                  "key": "severity",
                  "value": "error",
                  "disabled": true
                },
                {
                  "key": "source",
                  "value": "meta_api",
                  "disabled": true
                },
                {
                  "key": "wabaId",
                  "value": "texto",
                  "disabled": true
                },
                {
                  "key": "phoneNumberId",
                  "value": "texto",
                  "disabled": true
                },
                {
                  "key": "action",
                  "value": "texto",
                  "disabled": true,
                  "description": "O código estável do registro, como `template.rejected` ou `message.send`."
                },
                {
                  "key": "from",
                  "value": "2026-12-01T12:00:00Z",
                  "disabled": true,
                  "description": "Início do período, inclusivo (ISO 8601)."
                },
                {
                  "key": "to",
                  "value": "2026-12-01T12:00:00Z",
                  "disabled": true,
                  "description": "Fim do período, inclusivo. `2026-08-30` é meia-noite: para o dia inteiro, mande o instante final."
                },
                {
                  "key": "limit",
                  "value": "50",
                  "disabled": true,
                  "description": "Itens por página."
                },
                {
                  "key": "offset",
                  "value": "0",
                  "disabled": true,
                  "description": "Quantos itens pular. É com ele que se pagina."
                }
              ]
            },
            "description": "O que deu errado com a sua conta do WhatsApp, do mais recente ao mais antigo.\nDiferente de `/events`, que traz o que a Meta mandou: aqui está o que **falhou**,\njá interpretado."
          },
          "response": []
        },
        {
          "id": "2635da5e-c3c9-5741-ae2d-918b571f75ad",
          "name": "Acessos da operação aos dados da conta",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/audit/operator-access",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "audit",
                "operator-access"
              ],
              "query": [
                {
                  "key": "from",
                  "value": "2026-12-01T12:00:00Z",
                  "disabled": true,
                  "description": "Início do período, inclusivo (ISO 8601)."
                },
                {
                  "key": "to",
                  "value": "2026-12-01T12:00:00Z",
                  "disabled": true,
                  "description": "Fim do período, inclusivo. `2026-08-30` é meia-noite: para o dia inteiro, mande o instante final."
                },
                {
                  "key": "limit",
                  "value": "50",
                  "disabled": true,
                  "description": "Itens por página."
                },
                {
                  "key": "offset",
                  "value": "0",
                  "disabled": true,
                  "description": "Quantos itens pular. É com ele que se pagina."
                }
              ]
            },
            "description": "Quando a equipe do Joinotify abriu os dados da sua conta — conversas, mensagens,\ncontatos, campanhas, fluxos, eventos, faturamento —, do mais recente ao mais antigo.\nMostra onde e quando, não quem: o e-mail e o IP de quem acessou ficam com a operação.\nOs registros ficam guardados por 24 meses.\n\nUma API key restrita a alguns números recebe `403`: a trilha é da conta inteira."
          },
          "response": []
        }
      ]
    },
    {
      "id": "9f4af0eb-e7f2-5c38-aa7e-65ddc11f1add",
      "name": "Espelho (/v1)",
      "item": [
        {
          "id": "5385b93e-01ec-52c3-aa4b-b15f53365061",
          "name": "Números",
          "description": "Endpoints da Meta Cloud API relacionados a números de telefone e à listagem de\nnúmeros da WABA.\n\nSe você ainda não sabe seu `phone_number_id` ou `waba_id`, consulte antes\n`GET /me`.",
          "item": [
            {
              "id": "60b38dbe-344f-53f3-af85-3588c06e5e4f",
              "name": "Listar números da WABA",
              "request": {
                "method": "GET",
                "header": [],
                "url": {
                  "raw": "{{baseUrl}}/v1/:waba_id/phone_numbers",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "v1",
                    ":waba_id",
                    "phone_numbers"
                  ],
                  "query": [
                    {
                      "key": "fields",
                      "value": "id,display_phone_number,verified_name,quality_rating",
                      "disabled": true,
                      "description": "Campos a retornar, separados por vírgula. Sem ele, a Meta devolve o conjunto\npadrão."
                    }
                  ],
                  "variable": [
                    {
                      "key": "waba_id",
                      "value": "{{wabaId}}",
                      "description": "ID da conta empresarial na Meta. Precisa pertencer à sua conta."
                    }
                  ]
                },
                "description": "Lista os números da conta empresarial, com nome de exibição, status de\nverificação e qualidade.\n\nPasse `fields` para escolher o que vem na resposta. Sem ele, a Meta devolve o\nconjunto padrão."
              },
              "response": []
            },
            {
              "id": "4ada3dec-13db-5d4a-a0b4-bdc3b0fc9d12",
              "name": "Buscar recurso por ID",
              "request": {
                "method": "GET",
                "header": [],
                "url": {
                  "raw": "{{baseUrl}}/v1/:resource_id",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "v1",
                    ":resource_id"
                  ],
                  "query": [
                    {
                      "key": "fields",
                      "value": "id,display_phone_number,verified_name,quality_rating",
                      "disabled": true,
                      "description": "Campos a retornar, separados por vírgula. Sem ele, a Meta devolve o conjunto\npadrão."
                    }
                  ],
                  "variable": [
                    {
                      "key": "resource_id",
                      "value": "{{resourceId}}",
                      "description": "ID de qualquer recurso da Graph API: número, conta empresarial, template,\nmídia ou cadastro de opt-in."
                    }
                  ]
                },
                "description": "Busca qualquer recurso da Graph API pelo seu ID: um número\n(`phone_number_id`), uma conta empresarial (`waba_id`), um template ou uma\nmídia (`media_id`).\n\nO que volta depende do tipo do recurso e dos `fields` pedidos. Para mídia, a\nresposta traz uma `url` temporária que exige o header `Authorization` para o\ndownload."
              },
              "response": []
            },
            {
              "id": "471cccdc-5eaf-5da0-a7f7-389f720525b9",
              "name": "Listar QR Codes do número",
              "request": {
                "method": "GET",
                "header": [],
                "url": {
                  "raw": "{{baseUrl}}/v1/:phone_number_id/qr_codes",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "v1",
                    ":phone_number_id",
                    "qr_codes"
                  ],
                  "variable": [
                    {
                      "key": "phone_number_id",
                      "value": "{{phoneNumberId}}",
                      "description": "ID do número na Meta. Precisa pertencer à sua conta."
                    }
                  ]
                },
                "description": "Lista os QR Codes de entrada configurados no número."
              },
              "response": []
            },
            {
              "id": "86ecf8ab-a535-576c-ad90-5e577c52855f",
              "name": "Criar ou atualizar QR Code",
              "request": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"prefilled_message\": \"Quero saber sobre o meu pedido\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                },
                "url": {
                  "raw": "{{baseUrl}}/v1/:phone_number_id/qr_codes",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "v1",
                    ":phone_number_id",
                    "qr_codes"
                  ],
                  "variable": [
                    {
                      "key": "phone_number_id",
                      "value": "{{phoneNumberId}}",
                      "description": "ID do número na Meta. Precisa pertencer à sua conta."
                    }
                  ]
                },
                "description": "Cria um QR Code. Informe `code` para **atualizar** um existente em vez de\ncriar outro."
              },
              "response": []
            },
            {
              "id": "786be55b-9ca2-5a15-a35f-cdd1742c6fc3",
              "name": "Deletar QR Code do número",
              "request": {
                "method": "DELETE",
                "header": [],
                "url": {
                  "raw": "{{baseUrl}}/v1/:phone_number_id/qr_codes?code=texto",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "v1",
                    ":phone_number_id",
                    "qr_codes"
                  ],
                  "query": [
                    {
                      "key": "code",
                      "value": "texto"
                    }
                  ],
                  "variable": [
                    {
                      "key": "phone_number_id",
                      "value": "{{phoneNumberId}}",
                      "description": "ID do número na Meta. Precisa pertencer à sua conta."
                    }
                  ]
                },
                "description": "Remove o QR Code identificado por `code`."
              },
              "response": []
            }
          ]
        },
        {
          "id": "6cdc969e-fbbd-5f30-ab15-184f8074e43a",
          "name": "Templates",
          "description": "Gestão de templates via Meta Cloud API, no contrato original.\n\nPara listar e remover templates de forma simplificada, use `GET /templates` e\n`DELETE /templates/{name}`.",
          "item": [
            {
              "id": "7c7ceb06-84f7-59c6-a822-76a6ebbf21d2",
              "name": "Editar recurso por ID",
              "request": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"components\": [\n    {\n      \"type\": \"BODY\",\n      \"text\": \"Olá {{1}}, seu pedido {{2}} saiu para entrega.\",\n      \"example\": {\n        \"body_text\": [\n          [\n            \"Maria\",\n            \"1042\"\n          ]\n        ]\n      }\n    }\n  ]\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                },
                "url": {
                  "raw": "{{baseUrl}}/v1/:resource_id",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "v1",
                    ":resource_id"
                  ],
                  "variable": [
                    {
                      "key": "resource_id",
                      "value": "{{resourceId}}",
                      "description": "ID de qualquer recurso da Graph API: número, conta empresarial, template,\nmídia ou cadastro de opt-in."
                    }
                  ]
                },
                "description": "Edita um recurso da Graph API pelo seu ID. O corpo aceito depende do tipo.\n\n**Template** — só templates em `APPROVED` ou `REJECTED` podem ser editados, e\na edição joga o template de volta para `PENDING`. Nome, idioma e categoria\n**não** podem ser alterados; para isso, crie um template novo.\n\n**Cadastro no App** — atualiza `name`, `confirmation_message` ou `promo_code`.\nO deep link continua o mesmo, então links já distribuídos não quebram."
              },
              "response": []
            },
            {
              "id": "8c0c148c-cc33-5492-a717-762c16cf275a",
              "name": "Listar templates da WABA",
              "request": {
                "method": "GET",
                "header": [],
                "url": {
                  "raw": "{{baseUrl}}/v1/:waba_id/message_templates",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "v1",
                    ":waba_id",
                    "message_templates"
                  ],
                  "query": [
                    {
                      "key": "fields",
                      "value": "id,display_phone_number,verified_name,quality_rating",
                      "disabled": true,
                      "description": "Campos a retornar, separados por vírgula. Sem ele, a Meta devolve o conjunto\npadrão."
                    },
                    {
                      "key": "limit",
                      "value": "1",
                      "disabled": true
                    }
                  ],
                  "variable": [
                    {
                      "key": "waba_id",
                      "value": "{{wabaId}}",
                      "description": "ID da conta empresarial na Meta. Precisa pertencer à sua conta."
                    }
                  ]
                },
                "description": "Lista os templates direto da Meta, sem passar pelo espelho local. Use quando\nprecisar do dado cru; para uma listagem mais rápida, prefira `GET /templates`."
              },
              "response": []
            },
            {
              "id": "6bfe582f-6026-533c-abe0-31617bafb1c1",
              "name": "Criar template na WABA",
              "request": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"name\": \"confirmacao_pedido\",\n  \"category\": \"UTILITY\",\n  \"language\": \"pt_BR\",\n  \"components\": [\n    {\n      \"type\": \"BODY\",\n      \"text\": \"Olá {{1}}, seu pedido {{2}} foi confirmado.\",\n      \"example\": {\n        \"body_text\": [\n          [\n            \"Maria\",\n            \"1042\"\n          ]\n        ]\n      }\n    }\n  ]\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                },
                "url": {
                  "raw": "{{baseUrl}}/v1/:waba_id/message_templates",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "v1",
                    ":waba_id",
                    "message_templates"
                  ],
                  "variable": [
                    {
                      "key": "waba_id",
                      "value": "{{wabaId}}",
                      "description": "ID da conta empresarial na Meta. Precisa pertencer à sua conta."
                    }
                  ]
                },
                "description": "Cria um template no contrato original da Meta, sem a validação prévia de\nvariáveis e exemplos que `POST /templates` faz.\n\nSe você não tem motivo específico para usar o formato bruto, prefira\n`POST /templates`: os erros de exemplo aparecem na hora, em vez de virarem uma\nrejeição horas depois."
              },
              "response": []
            },
            {
              "id": "99d3bf17-bb0c-5722-a4d5-0cea084fae07",
              "name": "Deletar template",
              "request": {
                "method": "DELETE",
                "header": [],
                "url": {
                  "raw": "{{baseUrl}}/v1/:waba_id/message_templates?name=texto",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "v1",
                    ":waba_id",
                    "message_templates"
                  ],
                  "query": [
                    {
                      "key": "name",
                      "value": "texto"
                    },
                    {
                      "key": "hsm_id",
                      "value": "texto",
                      "disabled": true,
                      "description": "Apaga somente o idioma correspondente a este ID."
                    }
                  ],
                  "variable": [
                    {
                      "key": "waba_id",
                      "value": "{{wabaId}}",
                      "description": "ID da conta empresarial na Meta. Precisa pertencer à sua conta."
                    }
                  ]
                },
                "description": "Remove um template pelo nome. Informe `hsm_id` junto com `name` para apagar\napenas um idioma específico em vez de todos."
              },
              "response": []
            }
          ]
        },
        {
          "id": "62c25443-b547-587d-a399-d2d0e725ca91",
          "name": "Mídia",
          "description": "Upload, download e remoção de mídia na infraestrutura da Meta.\n\nArquivos enviados ficam disponíveis por 30 dias. A URL retornada por\n`GET /v1/{resource_id}` é temporária e exige o header `Authorization` para ser\nbaixada.",
          "item": [
            {
              "id": "996f4b41-d1b1-5257-ac8f-f02afbb39c6e",
              "name": "Deletar mídia",
              "request": {
                "method": "DELETE",
                "header": [],
                "url": {
                  "raw": "{{baseUrl}}/v1/:resource_id",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "v1",
                    ":resource_id"
                  ],
                  "variable": [
                    {
                      "key": "resource_id",
                      "value": "{{resourceId}}",
                      "description": "ID de qualquer recurso da Graph API: número, conta empresarial, template,\nmídia ou cadastro de opt-in."
                    }
                  ]
                },
                "description": "Remove um arquivo enviado, pelo `media_id`. Mensagens já entregues com essa\nmídia continuam funcionando para o cliente."
              },
              "response": []
            },
            {
              "id": "24264d11-70c3-5b6a-ae0c-19e6772ed3db",
              "name": "Upload de mídia",
              "request": {
                "method": "POST",
                "header": [],
                "body": {
                  "mode": "formdata",
                  "formdata": [
                    {
                      "key": "messaging_product",
                      "type": "text",
                      "value": "whatsapp"
                    },
                    {
                      "key": "file",
                      "type": "file",
                      "src": []
                    },
                    {
                      "key": "type",
                      "type": "text",
                      "value": "texto",
                      "disabled": true,
                      "description": "MIME type do arquivo, ex. `image/png`."
                    }
                  ]
                },
                "url": {
                  "raw": "{{baseUrl}}/v1/:phone_number_id/media",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "v1",
                    ":phone_number_id",
                    "media"
                  ],
                  "variable": [
                    {
                      "key": "phone_number_id",
                      "value": "{{phoneNumberId}}",
                      "description": "ID do número na Meta. Precisa pertencer à sua conta."
                    }
                  ]
                },
                "description": "Envia um arquivo para a infraestrutura da Meta e devolve um `id` reutilizável\nem vários envios. O arquivo fica disponível por **30 dias**.\n\nEnviar por `id` é mais rápido e confiável que por URL pública quando o mesmo\narquivo vai para muitos destinatários — a Meta baixa uma vez só.\n\nEsta rota tem um limite de uso próprio: **60 requisições por minuto**."
              },
              "response": []
            }
          ]
        },
        {
          "id": "890d7d09-f22f-5ce1-a0cb-a174f6c1b12d",
          "name": "Mensagens",
          "description": "Envio de mensagens via Meta Cloud API no formato bruto.\n\nPara uma experiência simplificada, sem montar o payload completo, use os\nendpoints da seção **Mensagens**.",
          "item": [
            {
              "id": "a41f7db4-94c2-5446-a845-4466de361836",
              "name": "Enviar mensagem",
              "request": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"messaging_product\": \"whatsapp\",\n  \"to\": \"5541987111527\",\n  \"type\": \"text\",\n  \"text\": {\n    \"body\": \"Olá!\"\n  }\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                },
                "url": {
                  "raw": "{{baseUrl}}/v1/:phone_number_id/messages",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "v1",
                    ":phone_number_id",
                    "messages"
                  ],
                  "variable": [
                    {
                      "key": "phone_number_id",
                      "value": "{{phoneNumberId}}",
                      "description": "ID do número na Meta. Precisa pertencer à sua conta."
                    }
                  ]
                },
                "description": "Endpoint de envio da Meta Cloud API, no formato bruto. Cobre todos os tipos de\nmensagem através do campo `type`.\n\n`context.message_id` é opcional — preencha só quando quiser responder citando\numa mensagem recebida.\n\nEste mesmo endpoint marca mensagens como lidas: envie\n`{ \"messaging_product\": \"whatsapp\", \"status\": \"read\", \"message_id\": \"wamid...\" }`.\n\nPara uma experiência sem montar o payload, use os endpoints da seção\n**Mensagens**."
              },
              "response": []
            }
          ]
        },
        {
          "id": "e0621da6-ecfd-504e-ad35-522b5eaa0522",
          "name": "Perfil empresarial",
          "description": "Perfil comercial do número no contrato original da Meta, incluindo o fluxo de\nalteração do nome de exibição.",
          "item": [
            {
              "id": "c70a1554-dcb7-5c44-a827-c3bfd2a7621f",
              "name": "Obter perfil empresarial",
              "request": {
                "method": "GET",
                "header": [],
                "url": {
                  "raw": "{{baseUrl}}/v1/:phone_number_id/whatsapp_business_profile",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "v1",
                    ":phone_number_id",
                    "whatsapp_business_profile"
                  ],
                  "query": [
                    {
                      "key": "fields",
                      "value": "id,display_phone_number,verified_name,quality_rating",
                      "disabled": true,
                      "description": "Campos a retornar, separados por vírgula. Sem ele, a Meta devolve o conjunto\npadrão."
                    }
                  ],
                  "variable": [
                    {
                      "key": "phone_number_id",
                      "value": "{{phoneNumberId}}",
                      "description": "ID do número na Meta. Precisa pertencer à sua conta."
                    }
                  ]
                },
                "description": "Devolve o perfil comercial do número. Passe `fields` para escolher o que vem —\npor exemplo `about,address,description,email,profile_picture_url,websites,vertical`."
              },
              "response": []
            },
            {
              "id": "48bdd055-1dfc-5c15-afae-1d973138d49a",
              "name": "Atualizar perfil empresarial",
              "request": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"messaging_product\": \"whatsapp\",\n  \"about\": \"Atendimento de segunda a sexta, das 9h às 18h.\",\n  \"websites\": [\n    \"https://loja.exemplo.com\"\n  ]\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                },
                "url": {
                  "raw": "{{baseUrl}}/v1/:phone_number_id/whatsapp_business_profile",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "v1",
                    ":phone_number_id",
                    "whatsapp_business_profile"
                  ],
                  "variable": [
                    {
                      "key": "phone_number_id",
                      "value": "{{phoneNumberId}}",
                      "description": "ID do número na Meta. Precisa pertencer à sua conta."
                    }
                  ]
                },
                "description": "Atualiza os campos informados. Campos omitidos ficam como estão.\n\n`profile_picture_handle` vem de um upload prévio pela Resumable Upload API."
              },
              "response": []
            }
          ]
        },
        {
          "id": "9aef9a1e-19a0-59ed-a862-5cba9bfbbea5",
          "name": "Bloqueios",
          "description": "Lista, bloqueia e desbloqueia números. Um número bloqueado não consegue mais\nenviar mensagens para o seu WhatsApp Business.",
          "item": [
            {
              "id": "e50583cc-2477-5160-a1d9-cfe75ff3d84a",
              "name": "Listar bloqueados",
              "request": {
                "method": "GET",
                "header": [],
                "url": {
                  "raw": "{{baseUrl}}/v1/:phone_number_id/block_users",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "v1",
                    ":phone_number_id",
                    "block_users"
                  ],
                  "query": [
                    {
                      "key": "limit",
                      "value": "1",
                      "disabled": true
                    },
                    {
                      "key": "after",
                      "value": "texto",
                      "disabled": true,
                      "description": "Cursor de paginação devolvido na página anterior."
                    }
                  ],
                  "variable": [
                    {
                      "key": "phone_number_id",
                      "value": "{{phoneNumberId}}",
                      "description": "ID do número na Meta. Precisa pertencer à sua conta."
                    }
                  ]
                },
                "description": "Lista os números bloqueados, com paginação por cursor."
              },
              "response": []
            },
            {
              "id": "02c72abd-a0a2-5826-a87b-ec88fa858f3c",
              "name": "Bloquear usuários",
              "request": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"messaging_product\": \"whatsapp\",\n  \"block_users\": [\n    {\n      \"user\": \"5541999999999\"\n    }\n  ]\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                },
                "url": {
                  "raw": "{{baseUrl}}/v1/:phone_number_id/block_users",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "v1",
                    ":phone_number_id",
                    "block_users"
                  ],
                  "variable": [
                    {
                      "key": "phone_number_id",
                      "value": "{{phoneNumberId}}",
                      "description": "ID do número na Meta. Precisa pertencer à sua conta."
                    }
                  ]
                },
                "description": "Bloqueia um ou mais números. Um número bloqueado não consegue mais enviar\nmensagens para o seu WhatsApp Business.\n\nA Meta só aceita bloquear quem já trocou mensagem com você."
              },
              "response": []
            },
            {
              "id": "7f010b8e-98b3-5db7-ae5f-5acd2a7cf487",
              "name": "Desbloquear usuários",
              "request": {
                "method": "DELETE",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"messaging_product\": \"whatsapp\",\n  \"block_users\": [\n    {\n      \"user\": \"5541999999999\"\n    }\n  ]\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                },
                "url": {
                  "raw": "{{baseUrl}}/v1/:phone_number_id/block_users",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "v1",
                    ":phone_number_id",
                    "block_users"
                  ],
                  "variable": [
                    {
                      "key": "phone_number_id",
                      "value": "{{phoneNumberId}}",
                      "description": "ID do número na Meta. Precisa pertencer à sua conta."
                    }
                  ]
                },
                "description": "Desbloqueia um ou mais números."
              },
              "response": []
            }
          ]
        },
        {
          "id": "49679b45-de5a-54f2-a7f6-0c353b5f0f80",
          "name": "Sincronização",
          "description": "Sincroniza o **histórico de conversas** e a **lista de contatos** do WhatsApp\nBusiness App (modo coexistência) para a Cloud API.\n\nA sincronização é disparada manualmente depois que o cliente conecta o número\nvia Embedded Signup — e precisa acontecer dentro de **24 horas**.\n\n## Pré-requisitos\n\n1. **O cliente autorizou o compartilhamento no celular.** Durante o Embedded\n   Signup, o WhatsApp Business App pede permissão para compartilhar histórico e\n   contatos. Se ele recusou, nada será enviado.\n2. **Os campos de webhook estão assinados.** Ative `history` e\n   `smb_app_state_sync` no endpoint de webhook do número.\n\n## Janela de 24 horas e disparo único\n\nVocê tem exatamente 24 horas a partir do Embedded Signup. Passou o prazo, não há\ncomo recuperar — o cliente precisa refazer o onboarding.\n\nCada tipo de sincronização (`history` e `smb_app_state_sync`) pode ser disparado\n**uma única vez por integração**.\n\n## Como o histórico chega\n\nEm múltiplos webhooks assíncronos, divididos em fases e blocos:\n\n| `phase` | Período nominal |\n|---|---|\n| `0` | dia 0 → dia 1 |\n| `1` | dia 1 → dia 90 |\n| `2` | dia 90 → dia 180 |\n\nNa prática **as fases se sobrepõem** — mensagens de qualquer data podem aparecer\nem qualquer fase. Não use a fase para inferir período; ordene tudo por\n`timestamp`.\n\nCada fase pode vir em vários blocos (`chunk_order`), não necessariamente em\nordem. O campo `progress` (0–100) indica o avanço geral: `progress: 100` na\núltima fase significa histórico completo.\n\nUm único webhook pode carregar milhares de mensagens:\n\n```\nwebhook (1 POST)\n└── value.history[]\n    └── threads[]       ← 1 thread = 1 conversa com 1 contato\n        └── messages[]  ← mensagens daquela conversa\n```\n\n## Duplicatas — regra obrigatória\n\nO mesmo `thread.id` aparece em vários webhooks e a mesma mensagem pode vir\nrepetida. Ao processar:\n\n1. Junte todas as mensagens com o mesmo `thread.id` de **todos** os webhooks.\n2. Deduplique por `wamid` (`message.id`).\n3. Ordene por `timestamp` (Unix em segundos, 10 dígitos).\n\nUse `history_context.from_me` para saber a direção: `true` = enviada pela\nempresa, `false` ou ausente = recebida.\n\n## Mídias no histórico\n\nMídias **não vêm dentro das threads** — aparecem como `type: \"media_placeholder\"`,\nsem conteúdo. O arquivo real chega em webhooks separados (`value.messages` ou\n`value.message_echoes`), casados pelo `wamid`. Só mídias dos últimos ~14 dias\ntêm arquivo disponível.\n\n## Contatos\n\nChegam geralmente em um único webhook, no array `state_sync`. Contas grandes\npodem gerar vários, sem ordenação garantida.\n\n- `action: \"add\"` → adicionar ou atualizar contato\n- `action: \"remove\"` → remover contato\n- Timestamp em **milissegundos** (13 dígitos) — diferente do histórico, que usa\n  segundos.\n\nDepois da sincronização inicial, alterações futuras nos contatos continuam\nchegando automaticamente por `smb_app_state_sync`, sem precisar chamar este\nendpoint de novo.",
          "item": [
            {
              "id": "e70f3381-8085-5e27-a7b8-8cecd5061698",
              "name": "Disparar sincronização",
              "request": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"messaging_product\": \"whatsapp\",\n  \"sync_type\": \"history\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                },
                "url": {
                  "raw": "{{baseUrl}}/v1/:phone_number_id/smb_app_data",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "v1",
                    ":phone_number_id",
                    "smb_app_data"
                  ],
                  "variable": [
                    {
                      "key": "phone_number_id",
                      "value": "{{phoneNumberId}}",
                      "description": "ID do número na Meta. Precisa pertencer à sua conta."
                    }
                  ]
                },
                "description": "Dispara a sincronização do histórico de conversas ou da lista de contatos do\nWhatsApp Business App para a Cloud API.\n\n:::danger Disparo único, janela de 24 horas\nCada tipo (`history` e `smb_app_state_sync`) pode ser disparado **uma única\nvez por integração**, e só dentro de **24 horas** após o Embedded Signup.\nErrou ou perdeu o prazo, o cliente precisa refazer o onboarding completo.\n:::\n\nA resposta é imediata e apenas confirma o agendamento. Os dados chegam depois,\nem múltiplos webhooks assíncronos — leia a descrição da seção **Espelho ·\nSincronização** para saber como montar as conversas a partir deles."
              },
              "response": []
            }
          ]
        },
        {
          "id": "0752ee66-09b0-5988-ac9f-cd8f0f109d02",
          "name": "Cadastro no App",
          "description": "Cria **deep links de opt-in** para que usuários do WhatsApp se inscrevam para\nreceber suas mensagens.\n\nQuando o usuário clica no link e confirma, você recebe uma notificação de\nwebhook e ele recebe a mensagem de confirmação que você configurou.\n\n## Formato do deep link\n\nDepois de criar um cadastro, use o `id` retornado com o número:\n\n```\nwa.me/<PHONE_NUMBER>/signup/<SIGNUP_ID>\n```\n\nO cadastro não fica preso a um número específico — o mesmo `signup_id` funciona\ncom qualquer número da sua WABA.\n\n## Termos de Serviço\n\nNa **primeira** criação, inclua o objeto `policy` com `tos` e `accepted: true`.\nAs chamadas seguintes não precisam disso.\n\n## Códigos promocionais\n\nUse `{{promo_code}}` no `confirmation_message` e informe o valor em\n`promo_code`. O placeholder é substituído na mensagem entregue ao usuário.\n\nQuem assina por um deep link entra automaticamente na base de clientes padrão da\nWABA.\n\n## Consultar ou editar um cadastro\n\nA Meta expõe um cadastro individual na raiz da Graph API, pelo próprio ID — não\nhá um caminho `/signups/{id}`. Use `GET /v1/{resource_id}` para consultar e\n`POST /v1/{resource_id}` para editar, passando o `signup_id` como\n`resource_id`.",
          "item": [
            {
              "id": "9c217e71-48c8-588a-a23e-436f77101c1e",
              "name": "Listar cadastros",
              "request": {
                "method": "GET",
                "header": [],
                "url": {
                  "raw": "{{baseUrl}}/v1/:waba_id/signups",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "v1",
                    ":waba_id",
                    "signups"
                  ],
                  "query": [
                    {
                      "key": "fields",
                      "value": "id,display_phone_number,verified_name,quality_rating",
                      "disabled": true,
                      "description": "Campos a retornar, separados por vírgula. Sem ele, a Meta devolve o conjunto\npadrão."
                    }
                  ],
                  "variable": [
                    {
                      "key": "waba_id",
                      "value": "{{wabaId}}",
                      "description": "ID da conta empresarial na Meta. Precisa pertencer à sua conta."
                    }
                  ]
                },
                "description": "Lista os cadastros de opt-in da conta empresarial."
              },
              "response": []
            },
            {
              "id": "680c62f8-3b66-553d-ad6a-84be1b1593bf",
              "name": "Criar cadastro",
              "request": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"name\": \"Clube de ofertas\",\n  \"confirmation_message\": \"Pronto! Você vai receber nossas ofertas.\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                },
                "url": {
                  "raw": "{{baseUrl}}/v1/:waba_id/signups",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "v1",
                    ":waba_id",
                    "signups"
                  ],
                  "variable": [
                    {
                      "key": "waba_id",
                      "value": "{{wabaId}}",
                      "description": "ID da conta empresarial na Meta. Precisa pertencer à sua conta."
                    }
                  ]
                },
                "description": "Cria um cadastro de opt-in e devolve o `id` usado no deep link\n`wa.me/<PHONE_NUMBER>/signup/<SIGNUP_ID>`.\n\nNa **primeira** criação, inclua `policy` com `tos.accepted: true`. As chamadas\nseguintes não precisam.\n\nExige a permissão `whatsapp_business_management`."
              },
              "response": []
            }
          ]
        },
        {
          "id": "e96c4c42-b1b0-5187-ad6b-302de2fc1cce",
          "name": "Bases de clientes",
          "description": "Bases de clientes para envio segmentado.\n\nUma base padrão é criada automaticamente no seu primeiro Cadastro no App — só\nvale gerenciar manualmente se você quiser separar assinantes em várias bases.",
          "item": [
            {
              "id": "eff2854a-fca0-5d4c-ab55-1c45fc208dd2",
              "name": "Listar bases de clientes",
              "request": {
                "method": "GET",
                "header": [],
                "url": {
                  "raw": "{{baseUrl}}/v1/:business_id/messaging_customer_base",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "v1",
                    ":business_id",
                    "messaging_customer_base"
                  ],
                  "query": [
                    {
                      "key": "fields",
                      "value": "id,display_phone_number,verified_name,quality_rating",
                      "disabled": true,
                      "description": "Campos a retornar, separados por vírgula. Sem ele, a Meta devolve o conjunto\npadrão."
                    }
                  ],
                  "variable": [
                    {
                      "key": "business_id",
                      "value": "{{businessId}}",
                      "description": "ID do negócio na Meta, obtido em `GET /me`."
                    }
                  ]
                },
                "description": "Lista as bases de clientes do negócio."
              },
              "response": []
            },
            {
              "id": "0fc32f95-81f8-5818-a90c-9be3c1932ce5",
              "name": "Criar base de clientes",
              "request": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"name\": \"Clientes da loja\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                },
                "url": {
                  "raw": "{{baseUrl}}/v1/:business_id/messaging_customer_base",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "v1",
                    ":business_id",
                    "messaging_customer_base"
                  ],
                  "variable": [
                    {
                      "key": "business_id",
                      "value": "{{businessId}}",
                      "description": "ID do negócio na Meta, obtido em `GET /me`."
                    }
                  ]
                },
                "description": "Cria uma base de clientes para envio segmentado. O `business_id` sai de\n`GET /me`."
              },
              "response": []
            },
            {
              "id": "3d6a5e19-b97d-5458-aee8-5d5c39fcc601",
              "name": "Obter base padrão da WABA",
              "request": {
                "method": "GET",
                "header": [],
                "url": {
                  "raw": "{{baseUrl}}/v1/:waba_id/default_messaging_customer_base",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "v1",
                    ":waba_id",
                    "default_messaging_customer_base"
                  ],
                  "variable": [
                    {
                      "key": "waba_id",
                      "value": "{{wabaId}}",
                      "description": "ID da conta empresarial na Meta. Precisa pertencer à sua conta."
                    }
                  ]
                },
                "description": "Devolve a base de clientes padrão da conta empresarial."
              },
              "response": []
            },
            {
              "id": "4cc33600-7b5d-54ea-a0b0-b4cd5ae82885",
              "name": "Definir base padrão da WABA",
              "request": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"messaging_customer_base_id\": \"{{customerBaseId}}\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                },
                "url": {
                  "raw": "{{baseUrl}}/v1/:waba_id/default_messaging_customer_base",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "v1",
                    ":waba_id",
                    "default_messaging_customer_base"
                  ],
                  "variable": [
                    {
                      "key": "waba_id",
                      "value": "{{wabaId}}",
                      "description": "ID da conta empresarial na Meta. Precisa pertencer à sua conta."
                    }
                  ]
                },
                "description": "Define em qual base entram os assinantes que chegam pelos deep links de\nCadastro no App."
              },
              "response": []
            }
          ]
        }
      ]
    }
  ],
  "variable": [
    {
      "key": "baseUrl",
      "value": "https://api.joinotify.com",
      "type": "string"
    },
    {
      "key": "audienceId",
      "value": "",
      "type": "string"
    },
    {
      "key": "broadcastId",
      "value": "",
      "type": "string"
    },
    {
      "key": "businessId",
      "value": "",
      "type": "string"
    },
    {
      "key": "contactId",
      "value": "",
      "type": "string"
    },
    {
      "key": "conversationId",
      "value": "",
      "type": "string"
    },
    {
      "key": "customerBaseId",
      "value": "",
      "type": "string"
    },
    {
      "key": "deliveryId",
      "value": "",
      "type": "string"
    },
    {
      "key": "duplicateContactId",
      "value": "",
      "type": "string"
    },
    {
      "key": "fieldId",
      "value": "",
      "type": "string"
    },
    {
      "key": "flowId",
      "value": "",
      "type": "string"
    },
    {
      "key": "hookToken",
      "value": "",
      "type": "string"
    },
    {
      "key": "importId",
      "value": "",
      "type": "string"
    },
    {
      "key": "inboxMediaId",
      "value": "",
      "type": "string"
    },
    {
      "key": "invoiceId",
      "value": "",
      "type": "string"
    },
    {
      "key": "keyId",
      "value": "",
      "type": "string"
    },
    {
      "key": "licenseKey",
      "value": "",
      "type": "string"
    },
    {
      "key": "mediaContentType",
      "value": "image/jpeg",
      "type": "string"
    },
    {
      "key": "messageId",
      "value": "",
      "type": "string"
    },
    {
      "key": "phoneNumberId",
      "value": "",
      "type": "string"
    },
    {
      "key": "resourceId",
      "value": "",
      "type": "string"
    },
    {
      "key": "scheduledMessageId",
      "value": "",
      "type": "string"
    },
    {
      "key": "suppressionId",
      "value": "",
      "type": "string"
    },
    {
      "key": "tagId",
      "value": "",
      "type": "string"
    },
    {
      "key": "templateId",
      "value": "",
      "type": "string"
    },
    {
      "key": "templateName",
      "value": "",
      "type": "string"
    },
    {
      "key": "wabaId",
      "value": "",
      "type": "string"
    },
    {
      "key": "webhookEndpointId",
      "value": "",
      "type": "string"
    }
  ]
}
