Markdown
API autenticada · contatos

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
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"]
  }'
CampoComo usar
phone_number_idNúmero que fará o envio. Se omitido, usamos o número padrão da empresa da chave.
checked_atHorário da consulta. Não é a data do aceite nem uma reserva de permissão para o próximo envio.
items[].knownExiste um cadastro nesse número de envio. False não significa que a pessoa não tem WhatsApp.
items[].opt_inaccepted, 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_sourceQuando 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_allowedfalse 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_reasonopted_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
{
  "success": true,
  "data": {
    "phone_number_id": "123456789012345",
    "checked_at": "2026-11-06T15:00:00Z",
    "items": [
      {
        "to": "5511999999999",
        "known": true,
        "opt_in": "declined",
20 linhas
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
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"
  }'
CampoRegra
toTelefone com DDI e DDD no caminho. Não deduzimos o país nem acrescentamos 55.
event_idObrigató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.
stateaccepted 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_atData real da manifestação, com fuso. Até cinco minutos de tolerância futura. Registramos UTC com precisão de milissegundos.
sourceweb, app, form, phone, in_person ou other. A origem é declarada pela integração.
evidence_refObrigatório, até 200 caracteres. Referência à prova no seu sistema. Não envie chaves, documentos ou texto de conversas.
notice_versionOpcional, até 100 caracteres. Versão do aviso de consentimento que a pessoa viu.
idempotent_replaytrue 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.
contactEstado 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.

RespostaComo tratar
200Manifestação registrada ou repetição reconhecida. Guarde event_id e confira contact.
409 consent_event_conflictO 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_blockedO 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_consentO 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_requestCampo ausente, desconhecido ou inválido. Use error.details.fields para localizar o problema.
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 (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.

JSON · campos adicionais em message.received.data
{
  "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.