Skip to main content
O /v1/boot comprova o external_id e nada mais — um e-mail que vem junto é guardado como atributo, nunca como aresta de identidade. Os dois fluxos desta página são os que comprovam o endereço em si, porque chegam nele. Cada um responde com uma sessão uk_ct_… verificada, marca email_verified no contato e publica contact.email_verified. São superfície pública alcançada com uma chave publicável no corpo da requisição, a partir do seu próprio domínio, e mantêm a postura mais estrita da API: 202 incondicional no pedido, um só 401 para todo jeito de um resgate falhar, limites estritos por IP e tokens de uso único para tudo que chega por e-mail.
Nenhum dos dois cria conta. O endereço precisa já pertencer a um contato — criado pelo seu backend com POST /v1/contacts ou trazido por um boot — porque um fluxo que cunhasse contatos a partir de uma caixa de entrada seria uma segunda porta de cadastro ao lado da sua. O pedido continua respondendo 202 para um endereço que ninguém tem, então o endpoint não serve para descobrir quais têm.
Login sem senha para uma página que não tem sessão a oferecer: o e-mail de um ticket, a central de ajuda pública, o portal.
1

Pedir

202 incondicional. Válido por uma hora. Rate limit de 5 por hora por IP.
2

Resgatar

Responde o contato e uma sessão uk_ct_… verificada.
O resgate é atômico em SQL, então o link funciona exatamente uma vez. Usado, expirado e nunca existiu respondem o mesmo 401 — três verdades diferentes, uma resposta, de propósito.

Códigos por e-mail

O mesmo fluxo apresentado como seis dígitos. Prefira o código ao link quando ele vai ser digitado no aparelho que o pediu: um código sobrevive ao cliente de e-mail que abre links no navegador dele, e funciona quando a caixa de entrada está no celular e o login está no notebook.
1

Pedir

202 — sempre
Guarde o desafio na página. Ele não é uma sessão e nunca pode ser usado como uma. Vale por dez minutos. Rate limit de 5 por hora por IP.
2

Verificar

Responde o contato e uma sessão uk_ct_… verificada. O código chegou na caixa de entrada, então ele comprova o endereço exatamente como o link.
O desafio volta para qualquer endereço, tendo conta ou não — do contrário este endpoint seria justamente onde alguém descobre quais endereços têm. A verificação mantém a mesma linha: código errado, expirado, já usado e desafio que nunca teve código atrás dele respondem o mesmo 401 invalid_code.
Duas regras são o que torna seis dígitos seguros de aceitar, e as duas importam:
  • Cada código tem cinco tentativas. Um palpite gasta uma, certo ou errado, e o código morre quando acabam. Seis dígitos são um milhão, o que o rate limit sozinho não fecha.
  • Pedir um código novo gasta o anterior. Senão cada pedido somaria mais cinco palpites contra mais um número.
O código sozinho também não basta: ele só vale contra o desafio para o qual foi emitido, então um código lido por cima do ombro de alguém não abre nada sem o navegador que o pediu.

A sessão

Os dois fluxos devolvem uma sessão de contato uk_ct_…, válida por 30 dias, com verified: true. Use-a para as leituras do próprio contato:
Sair apaga a sessão — a próxima busca simplesmente não encontra nada. No SDK o par é requestEmailCode / signInWithEmailCode e requestMagicLink / redeemMagicLink no cliente; o /sign-in do portal é o fluxo por código desenhado por nós.