Arestas de identidade
Um contato é alcançado por arestas de identidade — valores que resolvem até ele. São três tipos:
Essa diferença é o modelo inteiro.
external_id e email são identificantes: um valor que já pertence a outro
contato é uma duplicata para unir à mão, nunca um reapontamento silencioso.
Mover um e-mail de um contato para outro em silêncio é como uma pessoa acaba lendo
os dados de outra.
anonymous_id é o oposto: um cookie de dispositivo pertence a quem entrou por
último, então o último a reivindicar leva.
Identify
POST /v1/contacts é cria-ou-atualiza. Envie o que o seu backend souber; pelo
menos uma entre external_id, email ou anonymous_id é obrigatória.
201 quando o contato foi criado, 200 quando já existia — os dois com created
no corpo, para você não precisar ler o status.
A ordem de resolução é external_id, depois email: a sua própria chave
primária é a afirmação mais forte.
Nome e e-mail são atributos. Uma mudança é uma mudança, não uma pessoa nova — eles
são atualizados a cada chamada.
A aresta de identidade de e-mail só é criada quando está livre. Um conflito
deixa a aresta onde está e entrega a você uma duplicata para resolver.
Uma chamada que carrega só um
anonymous_id é um avistamento de visitante, não uma
identificação. identified continua false.Absorvendo o visitante
Quando umanonymous_id chega junto com um tipo identificante, o contato-visitante
a que ele pertencia é absorvido pelo identificado — automaticamente, na mesma
transação.
Com uma condição: só se aquele visitante nunca tiver sido identificado. Um cookie
de dispositivo que já aponta para alguém com nome significa que o aparelho trocou
de mãos, então o id passa a apontar para a nova pessoa e nada é absorvido — o
histórico de quem veio antes é dela, não da máquina.
É esse o momento em que a atribuição se paga: a campanha que trouxe alguém até a
sua landing page foi registrada na linha anônima, semanas antes de essa pessoa ter
um nome, e sobrevive até o contato que você agora conhece.
Atribuição
Primeiro toque, capturado no visitante no primeiro carregamento e preservado através de todo merge:/v1/boot (da página, onde as UTMs de fato estão) ou em /v1/contacts a
partir do seu servidor.
Identificado e verificado
Duas flags diferentes, e a diferença importa.boolean
Este contato é mais que um visitante — um
external_id ou um e-mail se ligou
a ele. Ligar basta; comprovar é o que a próxima flag diz.boolean
O endereço foi comprovado, por algo que chegou nele e voltou: um magic
link ou um código de seis dígitos. Nada mais marca isso — nem um boot, nem
uma importação, nem o seu próprio servidor afirmando.
/v1/boot é guardado
na linha e nunca vira aresta de identidade, porque o HMAC comprova o external_id e
apenas o external_id. Um hash válido para o seu próprio id somado ao e-mail de
outra pessoa jamais pode tocar o contato dessa pessoa.
Existe ainda um terceiro verified, na
sessão de contato, que diz
que a identidade por trás daquela sessão foi comprovada. Parente, não igual.
Merges
Não existe desfazer. Então merges acontecem de propósito.{id} na URL é a origem — a linha que
desaparece — e target_id no corpo é a sobrevivente. Exige customers:write.
Todo merge grava um registro com quem fez, quando e o que se moveu:
400.
Merges automáticos acontecem — absorver um visitante no contato que acabou de
reivindicar o anonymous_id dele — e são registrados do mesmo jeito, com outro
kind.
Lendo contatos
Duas superfícies, duas posturas:limit (1 a 200, padrão 50) e offset. Um limit fora dessa
faixa é ignorado em vez de truncado, então cai no padrão — pedir 500 devolve 50,
não 200. O teto é deliberado: suficiente para uma tela, pequeno o bastante para
ninguém baixar a audiência inteira sem querer.