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./public/v1/contacts/consent/batchEnvie 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 "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. |
{
"success": true,
"data": {
"phone_number_id": "123456789012345",
"checked_at": "2026-11-06T15:00:00Z",
"items": [
{
"to": "5511999999999",
"known": true,
"opt_in": "declined",/public/v1/contacts/{to}/consentUse 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 -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. |
Receber uma saída sem comparar o texto do botão (link para esta seçã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.
{
"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. Não reative marketing ao receber uma mensagem comum ou uma entrega antiga de aceite.