# Consentimento e saída de promoções

Consulte a base em lotes e registre quando e onde a pessoa autorizou o contato. Mantenha a prova original no seu sistema.

`marketing_allowed` informa a ausência de bloqueio local para marketing. Esse campo pode ser verdadeiro para um contato desconhecido ou pendente: ele não comprova autorização. Importe o consentimento apenas quando existir uma manifestação real e verificável da pessoa.

> `opt_in: accepted` com `opt_in_source: inbound` registra que a pessoa escreveu para atendimento. Não conte esses contatos como “autorizados para campanha”. Nos relatórios, separe origem inbound, declarações de consentimento com prova e recusas. Mesmo uma declaração pela API exige a conferência da prova no sistema de origem e não supera uma saída posterior.

### POST /public/v1/contacts/consent/batch

Envie de 1 a 500 telefones internacionais por chamada. O lote consome uma requisição na cota da chave e faz uma leitura do cadastro local, sem consultar a Meta nem enviar mensagens. Números repetidos são removidos preservando a primeira posição. Se algum telefone estiver malformado, o lote inteiro retorna 422; corrija a lista antes de repetir.

cURL · consultar consentimentos

```bash
curl "https://api.patrociniotech.com/public/v1/contacts/consent/batch" \
  -H "Authorization: Bearer SUA_CHAVE" \
  -H "Content-Type: application/json" \
  --data '{
    "phone_number_id": "123456789012345",
    "recipients": ["5511999999999", "5521999999999"]
  }'
```

| Campo | Como usar |
| --- | --- |
| phone\_number\_id | Número que fará o envio. Se omitido, usamos o número padrão da empresa da chave. |
| checked\_at | Horário da consulta. Não é a data do aceite nem uma reserva de permissão para o próximo envio. |
| items\[\].known | Existe um cadastro nesse número de envio. False não significa que a pessoa não tem WhatsApp. |
| items\[\].opt\_in | accepted, pending, declined ou null se não há cadastro. Descreve o número selecionado, conforme opt\_in\_scope: phone\_number. |
| items\[\].opt\_in\_at / opt\_in\_source | Quando e por qual origem o estado local foi registrado. null significa ausência de informação legada. inbound, manual ou import não são, por si só, prova de autorização para uma campanha. |
| items\[\].marketing\_allowed | false se houver recusa em qualquer número da empresa ou bloqueio no número consultado. true indica somente ausência dessas restrições locais. |
| items\[\].marketing\_block\_reason | opted\_out para saída de promoções; blocked para bloqueio no número consultado; null sem restrição local. |
| items\[\].latest\_api\_record | Última declaração recebida pela API para esse número, com data, origem e referência à prova. É histórico: uma saída posterior pode impedir marketing mesmo quando o registro anterior diz accepted. |

JSON · contato com saída registrada

```json
{
  "success": true,
  "data": {
    "phone_number_id": "123456789012345",
    "checked_at": "2026-11-06T15:00:00Z",
    "items": [
      {
        "to": "5511999999999",
        "known": true,
        "opt_in": "declined",
        "opt_in_at": "2026-11-06T14:50:00Z",
        "opt_in_source": "opt_out",
        "opt_in_scope": "phone_number",
        "marketing_allowed": false,
        "marketing_block_reason": "opted_out",
        "latest_api_record": null
      }
    ]
  }
}
```

> Uma recusa de promoções vale para a empresa inteira. O cadastro de um número pode continuar accepted quando a recusa está em outro; nesse caso marketing\_allowed será false. Verifique esse campo ao preparar a lista e trate também recusas no envio, porque a situação pode mudar depois da consulta.

### PUT /public/v1/contacts/{to}/consent

Use esta rota para registrar uma manifestação coletada no site, aplicativo ou outro canal. A chave define a empresa e quem registrou a operação. A API guarda um histórico com a data declarada, a data de registro, a origem e a referência à prova; ela não verifica a autenticidade dessa prova nem substitui sua conservação.

cURL · registrar aceite coletado no site

```bash
curl -X PUT "https://api.patrociniotech.com/public/v1/contacts/5511999999999/consent" \
  -H "Authorization: Bearer SUA_CHAVE" \
  -H "Content-Type: application/json" \
  --data '{
    "phone_number_id": "123456789012345",
    "event_id": "consentimento-site-001",
    "state": "accepted",
    "occurred_at": "2026-11-06T11:40:00-03:00",
    "source": "web",
    "evidence_ref": "consentimentos/001",
    "notice_version": "marketing-v2"
  }'
```

| Campo | Regra |
| --- | --- |
| to | Telefone com DDI e DDD no caminho. Não deduzimos o país nem acrescentamos 55. |
| event\_id | Obrigatório, até 128 caracteres: letras ASCII, números, ponto, sublinhado, dois-pontos ou hífen. Identifica uma manifestação na empresa inteira; não reutilize para outra pessoa ou outro conteúdo. |
| state | accepted registra aceite no número escolhido. declined registra saída de marketing para a empresa inteira; não impede avisos transacionais legítimos de utilidade ou autenticação. |
| occurred\_at | Data real da manifestação, com fuso. Até cinco minutos de tolerância futura. Registramos UTC com precisão de milissegundos. |
| source | web, app, form, phone, in\_person ou other. A origem é declarada pela integração. |
| evidence\_ref | Obrigatório, até 200 caracteres. Referência à prova no seu sistema. Não envie chaves, documentos ou texto de conversas. |
| notice\_version | Opcional, até 100 caracteres. Versão do aviso de consentimento que a pessoa viu. |
| idempotent\_replay | true quando o evento já estava registrado com esse conteúdo. A repetição não reaplica o aceite: uma saída ocorrida depois continua respeitada. |
| contact | Estado atual do contato após o registro, no mesmo formato dos itens da consulta em lote. Pode refletir uma alteração posterior à manifestação original. |

Aceite registrado pela API usa `opt_in_source: api`; a origem detalhada, como web, fica em `latest_api_record.source`. Os registros legados permanecem como estão: não criamos datas ou provas retroativas. Registrar consentimento não envia mensagens nem abre uma janela de atendimento.

| Resposta | Como tratar |
| --- | --- |
| 200 | Manifestação registrada ou repetição reconhecida. Guarde event\_id e confira contact. |
| 409 consent\_event\_conflict | O event\_id já identifica outra declaração. Não altere dados de um evento existente; use a identidade correta da nova manifestação. |
| 409 consent\_blocked | O contato está bloqueado ou já pediu saída. A API não remove essa restrição. A equipe deve revisar a nova prova e o cadastro no painel. |
| 409 stale\_consent | O aceite enviado é anterior ao estado local atual. Não troque a data para contornar a validação; confira a manifestação mais recente. |
| 422 invalid\_request | Campo ausente, desconhecido ou inválido. Use error.details.fields para localizar o problema. |

> Atenção: Não transforme uma lista importada em accepted para liberar campanhas. Uma revogação posterior deve continuar valendo. Se houver timeout, repita o mesmo event\_id e conteúdo; não crie outra identidade para a mesma manifestação.

## Receber uma saída sem comparar o texto do botão

O evento `message.received` mantém os campos anteriores e acrescenta `interaction`, com o tipo, o ID/payload e o título do botão. Quando o Patrocinio reconhece e aplica um pedido de saída, `consent.action` será `marketing_opt_out` e `marketing_allowed` será false.

JSON · campos adicionais em message.received.data

```json
{
  "interaction": {
    "type": "button_reply",
    "id": "acao-saida-001",
    "title": "Parar promoções"
  },
  "consent": {
    "action": "marketing_opt_out",
    "marketing_allowed": false,
    "scope": "tenant",
    "changed": true
  }
}
```

Para mensagens sem ação de consentimento, `consent` é null; isso não significa aceite. Um pedido repetido pode ter `changed: false`, mantendo a pessoa fora das promoções. `interaction.id` preserva o valor recebido da Meta; ele não altera o consentimento sozinho.

Também é possível assinar `contact.marketing_opt_out` em Integrações. Ele é emitido quando o estado muda, tanto por pedido reconhecido no WhatsApp quanto por uma revogação registrada nesta API. Inclui `to`, `phone_number_id`, `source`, `occurred_at`, `scope: tenant` e `marketing_allowed: false`. No WhatsApp, `message_id` identifica o pedido; pela API, `event_id` identifica a declaração e message\_id é null.

O evento e o estado são gravados na mesma transação. A entrega HTTP pode ser repetida ou chegar fora de ordem: valide a assinatura e deduplique por [delivery\_id](https://patrociniotech.com/documentacao-api/webhook.md). Não reative marketing ao receber uma mensagem comum ou uma entrega antiga de aceite.

---

Fonte: https://patrociniotech.com/documentacao-api/consentimento
Índice para IA: https://patrociniotech.com/documentacao-api/llms.txt
