Documentação

Verificação de endereço físico

Confirme que uma pessoa recebe correspondência no endereço que informou, com uma correspondência com código e a sua marca.

A verificação de endereço físico confirma que uma pessoa recebe correspondência no endereço que ela informou. A CartaFlow envia para esse endereço uma correspondência com um código de 6 dígitos. Quando a pessoa confirma o código, o endereço fica verificado: só quem recebeu a correspondência conhece o código.

Por exemplo, uma fintech recebe um pedido de abertura de conta e pede a verificação do endereço informado. Quando a correspondência chega, o cliente vê o logo da fintech, escaneia o QR code e confirma. O cadastro passa a ter o endereço verificado.

A correspondência leva a sua marca

A correspondência de verificação sai em nome da sua empresa. Nem a correspondência nem a página de confirmação mostram o nome ou o logo da CartaFlow. Por enquanto, a página fica no domínio verifica.cartaflow.com.br, num endereço com o id da sua conta (é o link impresso na correspondência e o que o QR code abre); páginas no domínio da sua empresa podem vir depois. A página e o modelo da CartaFlow usam o seu logo e o nome fantasia da sua empresa (a razão social, quando não há nome fantasia). Configure os dois no painel, em Configurações > Empresa, antes da primeira verificação. No seu próprio PDF, a correspondência leva o layout e a marca do seu documento.

A correspondência pode sair de duas formas:

FormaQuando usarPreço
Modelo da CartaFlow (padrão)Você quer uma correspondência pronta, com o seu logo e os seus textos.Um envio simples do seu plano.
O seu próprio PDFVocê já tem um layout, como um documento do Word, e quer só incluir o código.O de uma correspondência com as mesmas opções.

Nas duas formas, a correspondência traz o código de 6 dígitos e, com method: hosted_page, pode trazer o QR code e o endereço da página de confirmação.

Três formas de usar

FormaComo a pessoa confirmaO que você constrói
Pelo painelNa página com a sua marca, pelo QR code.Nada. Você pede as verificações no painel e acompanha o resultado ali.
API com method: hosted_pageEscaneia o QR code e confirma em uma página com a sua marca, hospedada pela CartaFlow.A chamada que cria a verificação e um webhook para saber o resultado.
API com method: codeDigita o código no seu site ou aplicativo.A tela onde a pessoa digita o código e a chamada que confere o código.

Com hosted_page, o endereço da página fica em hosted_page_url. Você também pode mandar esse link por e-mail ou mostrar no seu app. Depois de confirmar, a página mostra um botão que leva a pessoa para return_url, se você enviou um.

O campo source diz por onde cada verificação foi criada: api ou dashboard. Ele não depende de como a pessoa confirma, que fica em confirmation. Por exemplo, uma verificação criada no painel é confirmada na página, e uma criada pela API com method: hosted_page pode ser confirmada na página ou conferida pelo seu servidor.

Criar uma verificação

No endereço, só name, postal_code e number são obrigatórios. O resto é preenchido a partir do CEP quando você não envia, como nas correspondências. Veja Endereços no Brasil.

curl -X POST "https://api.cartaflow.com.br/v1/verifications" \
  -H "Authorization: Bearer $CARTAFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: verificacao-cliente-1842" \
  -d '{
    "to": { "name": "Destinatário Exemplo", "postal_code": "01001-000", "number": "128", "complement": "Ap. 52" },
    "method": "hosted_page",
    "return_url": "https://www.exemplo.com.br/conta",
    "reference": "cliente-1842"
  }'

A resposta tem status received, source: "api" e attempts_remaining igual a 5. Sem letter nem document, a correspondência sai do modelo da CartaFlow, com os textos do modelo padrão da sua empresa. Com method: code, troque return_url por instructions, por exemplo "Abra o app, vá em Perfil > Endereço e digite o código.". Se você não enviar instructions, imprimimos um texto padrão com o nome da sua empresa.

Ninguém vê o código, nem você

Nem a API nem o painel mostram o código, para ninguém da sua empresa. Ele só existe na correspondência que a CartaFlow imprime, e é isso que prova o endereço. preview_url traz a correspondência como ela será impressa, com o endereço, mas com o código escondido: no lugar dele aparece 000 000, e no lugar do QR code, um quadro que mostra onde ele será impresso.

Modelo da CartaFlow

Sem document, a CartaFlow monta a correspondência: uma folha A4 em preto e branco com o seu logo, o nome da sua empresa, o endereço na janela do envelope, um título, um texto, o código e um rodapé. Com method: hosted_page, ela traz também o QR code, que abre a página já com o código, e o endereço da página, para quem prefere digitar.

O que vai impresso vem de três camadas, nesta ordem:

  1. O padrão da CartaFlow.
  2. O modelo padrão da sua empresa, salvo no painel. Vale para todas as verificações, criadas pela API ou pelo painel.
  3. O campo letter da requisição, só para esta verificação.

Cada campo que você não envia em letter vem da camada anterior.

Campo de letterO que éPadrão da CartaFlow
titleO título, em destaque. Até 80 caracteres.Confirme o seu endereço
bodyO texto antes do código. Até 1.200 caracteres.{{empresa}} pediu a confirmação de que você recebe correspondência neste endereço. Use o código abaixo para confirmar.
footerO texto do pé da página. Até 300 caracteres.O código vale por 60 dias depois da postagem e só funciona para este endereço. Não compartilhe este código com ninguém.
include_qr_codeImprime o QR code que abre a página já com o código.true
include_page_urlImprime o endereço da página de confirmação, para a pessoa abrir no navegador e digitar o código.true

Nos textos, você pode usar duas marcações: {{empresa}}, que vira o nome da sua empresa, e {{nome}}, que vira o nome do destinatário (to.name). Qualquer outra marcação entre chaves dá 422 com invalid_value.

Corpo da requisição com o modelo personalizado
{
  "to": { "name": "Destinatário Exemplo", "postal_code": "01001-000", "number": "128" },
  "method": "hosted_page",
  "letter": {
    "title": "Confirme seu endereço, {{nome}}",
    "body": "{{empresa}} precisa confirmar o endereço do seu cadastro. Use o código abaixo.",
    "include_page_url": false
  }
}
  • Com method: code, o QR code e o endereço da página nunca são impressos, mesmo com include_qr_code ou include_page_url em true. No lugar deles vai o texto de instructions.
  • O modelo usa sempre uma folha em preto e branco. color, double_sided e address_placement só valem com o seu próprio PDF.
  • A resposta traz em document o que foi usado, com type: "template" e os textos ainda com as marcações.

O seu próprio PDF

Envie o seu PDF em document, como numa correspondência: type: url, type: upload ou type: base64. Este endpoint aceita só JSON: para enviar o arquivo, use o upload em duas etapas. O PDF segue as regras de uma correspondência: A4 em retrato, até 6 folhas, texto selecionável e a área do endereço em branco, ou address_placement: extra_page. Veja Documento e área do endereço.

Escreva no documento as marcações que a CartaFlow preenche:

MarcaçãoObrigatóriaO que a CartaFlow imprime no lugar
{{OTP_CODE}}Sim. Sem ela, a API responde 422 com otp_code_missing.O código, no formato 123 456, com a fonte, o tamanho e a cor da marcação.
{{VERIFICATION_URL}}Não. Só com method: hosted_page.O endereço da página de confirmação, o mesmo de hosted_page_url, sem o código.
{{QR_CODE}}Não. Só com method: hosted_page.Um QR code de 25 x 25 mm que abre a página já com o código. O canto superior esquerdo fica onde começa a marcação.
  • Escreva as marcações em maiúsculas e com as chaves, como na tabela.
  • Deixe espaço depois de {{OTP_CODE}} para o código inteiro e, a partir de {{QR_CODE}}, um quadrado em branco de 25 mm para a direita e para baixo.
  • Com method: code, {{VERIFICATION_URL}} e {{QR_CODE}} dão 422 com invalid_value. Escreva no documento onde a pessoa digita o código.
  • As outras marcações, como {{nome}}, são variáveis comuns: envie os valores em document.variables. Não envie valores para as marcações reservadas: a API responde variable_not_found.
  • color, double_sided e address_placement funcionam como numa correspondência e entram no preço.
  • instructions não é impresso no seu PDF.
Corpo da requisição com o seu PDF, enviado antes com POST /v1/uploads
{
  "to": { "name": "Destinatário Exemplo", "postal_code": "01001-000", "number": "128" },
  "method": "hosted_page",
  "document": {
    "type": "upload",
    "upload_id": "upl_6Np3Vx8Rk2Tq",
    "variables": { "nome": "Destinatário Exemplo" }
  },
  "color": true,
  "reference": "cliente-2210"
}

A resposta traz em document a forma de envio (upload, url ou base64) e as variables que você enviou.

Confira a correspondência logo depois de criar

Abra preview_url assim que a verificação for criada. Enquanto ela está em received, você pode cancelar e o valor volta para o saldo.

Status

  1. Recebidareceived
    • Canceladacanceled
  2. Em produçãoin_production
    • Canceladacanceled
    • Revogadarevoked
  3. Aguardando códigoawaiting_code
    • Falhoufailed
    • Expiradaexpired
    • Revogadarevoked
  4. Verificadaverified
    • Revogadarevoked
StatusO que significaFinalCancelável
receivedRecebidaA CartaFlow recebeu o pedido, cobrou o preço do seu saldo e colocou a correspondência com o código na fila de produção. Se você cancelar agora, nada é impresso e o valor volta para o saldo.NãoSim
in_productionEm produçãoA correspondência com o código está sendo impressa e envelopada. Cancelar agora revoga a verificação (revoked), sem devolução do valor.NãoSim
awaiting_codeAguardando códigoA correspondência foi postada. Agora esperamos a pessoa confirmar o código. Ela tem 60 dias a partir da postagem (veja expires_at). Cancelar agora revoga a verificação, sem devolução do valor.NãoSim
verifiedVerificadaA pessoa confirmou o código certo. Ela recebe correspondência no endereço informado. confirmation diz como e quando. Você ainda pode revogar a verificação, e ela passa para revoked.NãoSim
failedFalhouForam digitados 5 códigos errados. A verificação foi bloqueada para impedir tentativas aleatórias. Crie uma nova verificação se quiser tentar de novo.SimNão
expiredExpiradaPassaram 60 dias desde a postagem sem que a pessoa confirmasse o código.SimNão
canceledCanceladaA verificação foi cancelada antes da postagem e o valor voltou para o seu saldo. Ou você cancelou enquanto ela estava em received, ou a CartaFlow cancelou porque a correspondência não pôde ser produzida.SimNão
revokedRevogadaVocê cancelou a verificação depois que a produção começou: em produção, aguardando código ou já verificada. O valor não volta para o saldo, porque a produção já começou, e uma correspondência que estava em produção ainda é postada. O código deixa de funcionar, na página e na API, e a verificação nunca mais aparece como verified.SimNão

O código só pode ser confirmado em awaiting_code, depois da postagem. A pessoa tem 60 dias a partir da postagem para confirmar. O prazo exato fica em expires_at. Depois dele, a verificação vai para expired.

verified não é o fim: se você revogar a verificação, ela passa para revoked. Trate um endereço como verificado só enquanto o status for verified.

Conferir o código digitado no seu app

Com method: code, a pessoa digita o código no seu site ou app, e o seu servidor confere com POST /v1/verifications/{verification_id}/check. Faça essa chamada sempre do servidor, nunca do navegador ou do app.

curl -X POST "https://api.cartaflow.com.br/v1/verifications/ver_8Wn2Rt6Yk4Js/check" \
  -H "Authorization: Bearer $CARTAFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "code": "482917" }'

Um código errado não é um erro da API. A resposta é sempre 200, com correct: false, e attempts_remaining diminui. Depois de 5 códigos errados, contando os digitados na página e pela API, a verificação vai para failed. Para tentar de novo, crie uma verificação nova.

Respostas de erro só acontecem quando a conferência não faz sentido no momento:

SituaçãoResposta
A correspondência ainda não foi postada, ou a verificação já terminou (verified, failed, expired, canceled, revoked).409 com verification_not_awaiting_code. A mensagem informa o status atual.
O código não tem 6 dígitos.422 com invalid_format em code. Essa tentativa não é contada.

A tela onde a pessoa digita o código

Algumas escolhas deixam a confirmação mais fácil:

  • Use um campo numérico (inputmode="numeric" e autocomplete="one-time-code") para 6 dígitos.
  • Aceite o código com espaços ou traços e remova esses caracteres antes de enviar.
  • Depois de um erro, diga quantas tentativas restam.
  • Quando a verificação estiver em failed ou expired, explique o que aconteceu e ofereça pedir uma nova correspondência.

Sugestões de mensagens:

SituaçãoMensagem
Código certoEndereço confirmado. Obrigado.
Código erradoEste código não confere. Você ainda tem 3 tentativas.
Última tentativaEste código não confere. Você tem mais 1 tentativa.
Sem tentativas (failed)Não foi possível confirmar o endereço com este código. Peça uma nova correspondência de verificação.
Prazo vencido (expired)O prazo para confirmar este código terminou. Peça uma nova correspondência de verificação.
Ainda não postada (409)A correspondência com o código ainda está a caminho. Tente quando ela chegar.
Cancelada ou revogada (409)Esta verificação foi cancelada. Se você esperava confirmar o seu endereço, fale com a gente.

Como a confirmação foi feita

Quando o código certo é confirmado, a verificação passa a ter confirmation. Antes disso, confirmation é null.

confirmation de uma verificação confirmada pelo QR code
"confirmation": {
  "method": "hosted_page",
  "hosted_page_entry": "qr_code",
  "confirmed_at": "2026-10-21T19:32:00Z",
  "ip": "198.51.100.23",
  "location": { "city": "São Paulo", "region": "SP", "country": "BR", "postal_code": "01000", "latitude": -23.5475, "longitude": -46.6361 },
  "user_agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.5 Mobile/15E148 Safari/604.1",
  "device": { "type": "mobile", "os": { "name": "iOS", "version": "17.5" }, "browser": { "name": "Safari", "version": "17.5" } },
  "client": { "language": "pt-BR", "accept_language": "pt-BR,pt;q=0.9", "timezone": "America/Sao_Paulo", "screen": { "width": 390, "height": 844, "pixel_ratio": 3 }, "time_on_page_ms": 8100 },
  "precise_location": {
    "latitude": -23.5489, "longitude": -46.6388, "accuracy_m": 14.5, "distance_m": 606,
    "shared_at": "2026-10-21T19:32:40Z", "ip": "198.51.100.23",
    "user_agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.5 Mobile/15E148 Safari/604.1",
    "address_coordinates": { "latitude": -23.5503898, "longitude": -46.633081 }
  }
}
CampoO que é
methodhosted_page, quando a pessoa confirmou na página, ou api, quando o seu servidor conferiu o código com /check.
hosted_page_entryNa página: qr_code, quando a pessoa escaneou o QR code, ou typed, quando digitou o código. null com method: api.
confirmed_atQuando o código certo foi confirmado.
ipO IP de onde veio a confirmação. Na página, é o do aparelho da pessoa. Pela API, é o do seu servidor, não o da pessoa.
locationCidade, região (no Brasil, a UF), país, código postal, latitude e longitude, estimados a partir do IP. Só na página; null pela API.
user_agentO user agent do navegador que confirmou. Pela API, o do seu servidor.
deviceTipo de aparelho (mobile, tablet ou desktop), sistema e navegador, com as versões, lidos do user_agent.
clientO idioma do navegador, o cabeçalho Accept-Language, o fuso horário, a tela e quanto tempo passou entre abrir a página e enviar o código. Pela API, só accept_language, quando o seu servidor envia.
precise_locationA localização do aparelho, só quando a pessoa escolhe compartilhar depois de confirmar (veja Localização opcional), com a distância até o CEP do endereço.

Cada campo que não pôde ser registrado vem null. Confirmações registradas antes de 14/10/2026 têm null em user_agent, device, client e precise_location.

IP, localização e aparelho são indícios

São registrados quando estão disponíveis e podem vir null. location vem da rede, não do GPS: uma rede móvel, uma VPN ou um proxy podem indicar outra cidade ou outro país. device e client vêm do que o navegador informa. Use tudo isso como indícios a mais numa análise de fraude, nunca como prova do endereço. A prova é o código, que só chega pela correspondência.

Uma verificação revogada depois de confirmada mantém confirmation e status_transitions.verified_at como registro, mas o status é revoked.

A página de confirmação

Com method: hosted_page, a CartaFlow hospeda a página onde a pessoa confirma, com o seu logo e o nome da sua empresa, e nada da CartaFlow: nem nome, nem logo, nem cores. O endereço é https://verifica.cartaflow.com.br/{id da sua conta}/{token da página}, o mesmo de hosted_page_url. Use o valor de hosted_page_url como veio, sem montar o endereço por conta própria.

O que a pessoa vê:

  • O seu logo e o nome fantasia da sua empresa (a razão social, quando não há nome fantasia).
  • Pelo QR code, a página abre com o código já preenchido: a pessoa toca uma vez em Confirmar endereço. Abrir o link nunca confirma sozinho.
  • Pelo endereço impresso, ou por hosted_page_url enviado por você, a pessoa digita os 6 dígitos.
  • O resultado: endereço confirmado, ou código errado com as tentativas que restam.
  • Depois de confirmar, um botão para return_url, se você enviou um, e a opção de compartilhar a localização.
  • Um aviso curto sobre o que é registrado para comprovar a confirmação e quem é responsável pelos dados.
  • O contato da sua empresa, quando configurado (abaixo).

A página é em português, funciona no celular e no computador, não é indexada por buscadores e não tem ferramentas de análise nem scripts de terceiros.

Quando a verificação não espera mais código, a página não aceita códigos e explica o motivo, citando a sua empresa e o seu contato:

StatusO que a página diz
received, in_productionA correspondência com o código ainda não foi postada.
verifiedO endereço já foi confirmado.
failedO código foi bloqueado depois de 5 tentativas erradas. A pessoa deve falar com a sua empresa para receber uma nova correspondência.
expiredO prazo para confirmar terminou. A pessoa deve falar com a sua empresa para receber um novo código.
canceled, revokedA verificação foi cancelada pela sua empresa. Se a pessoa esperava confirmar o endereço, deve falar com a sua empresa.

Prepare o seu atendimento para esses contatos.

O seu contato na página

Em Configurações > Empresa, você pode informar o site, o e-mail, o telefone e o endereço da política de privacidade da sua empresa. Todos são opcionais. A página mostra o que estiver preenchido, inclusive nas mensagens que pedem para a pessoa falar com a sua empresa, e o link da política de privacidade fica no aviso sobre os dados.

O que a página registra

Em cada tentativa, certa ou errada, a página registra: data e hora, IP, localização aproximada do IP, user agent, aparelho, sistema e navegador, idioma, fuso horário, tela, quanto tempo a pessoa ficou na página e se o código veio do QR code ou foi digitado. Tudo aparece no painel, no detalhe da verificação, e a confirmação aparece na API, em confirmation. Por enquanto, não é possível desligar nenhum desses registros.

Contra tentativas automáticas, além do limite de 5 códigos errados por verificação, a página limita as tentativas e as consultas por IP.

Localização opcional

Depois de confirmar o código, a página oferece "Compartilhar minha localização". Se a pessoa tocar e o navegador tiver permissão, a página envia a posição do aparelho, com a precisão informada por ele. Ela nunca é pedida antes do código, nunca é obrigatória e só é aceita uma vez, até 30 minutos depois da confirmação.

A localização fica em confirmation.precise_location, com a distância em metros até as coordenadas do CEP do endereço (distance_m). O CEP marca uma rua ou um trecho dela, não o número da casa, então uma distância de algumas centenas de metros é normal. distance_m vem null quando não temos as coordenadas desse CEP.

Acompanhar pelo webhook

O evento mais importante é verification.verified. Com method: hosted_page, é por ele que o seu sistema fica sabendo da confirmação, e data.confirmation diz como ela foi feita. Trate também verification.revoked: uma verificação revogada não conta mais como verificada, mesmo que tenha sido confirmada antes. Nos eventos, preview_url vem null: consulte a verificação para receber o link. Veja Webhooks.

EventoQuando é enviado
verification.receivedUma verificação foi criada, pela API ou pelo painel (veja source), e a correspondência com o código está na fila de produção.
verification.in_productionA correspondência com o código está sendo impressa. A partir daqui, cancelar revoga a verificação, sem devolução.
verification.awaiting_codeA correspondência com o código foi postada. A pessoa já pode confirmar quando receber.
verification.verifiedA pessoa confirmou o código certo. O endereço está verificado.
verification.failedForam digitados 5 códigos errados e a verificação foi bloqueada.
verification.expiredA pessoa não confirmou o código em 60 dias desde a postagem.
verification.canceledA verificação foi cancelada antes da postagem, por você ou pela CartaFlow, e o valor voltou para o saldo.
verification.revokedVocê cancelou a verificação depois que a produção começou. O código deixou de funcionar e o valor não volta para o saldo. Se ela estava verified, trate o endereço como não verificado.

Preço

Com o modelo da CartaFlow, cada verificação custa o mesmo que um envio simples do seu plano: uma linha base em price. Com o seu PDF, o preço é o de uma correspondência com as mesmas opções: base, mais additional_sheets e color quando se aplicam. Uma verificação vai sempre como carta simples, sem serviços dos Correios. O valor é debitado do saldo na criação. Veja Preços e saldo.

Cancelar ou revogar

POST /v1/verifications/{verification_id}/cancel cancela ou revoga a verificação, conforme o status. O painel faz o mesmo, com as mesmas regras.

StatusResultadoValor
receivedcanceled: nada é impresso.Volta para o saldo.
in_production, awaiting_code ou verifiedrevoked: o código deixa de funcionar, na página e na API, e a verificação nunca mais aparece como verified.Não volta.
canceled ou revokedNada muda: a resposta traz a mesma verificação.
failed ou expired409 com verification_not_cancelable.

Revogue quando o endereço não deve mais contar como verificado, por exemplo quando o cadastro foi encerrado ou você suspeita de fraude. Revogar não impede a entrega: uma correspondência que já estava em produção ainda é postada, e quem tentar confirmar o código vê o aviso para falar com a sua empresa.

Uma verificação também pode ir para canceled sem pedido seu, quando a correspondência não pode ser produzida. Nesse caso, o valor volta para o saldo automaticamente.

Use com consentimento

Peça a verificação só para um endereço que a própria pessoa informou a você, e diga a ela que uma correspondência com um código vai chegar. A correspondência é uma comunicação da sua empresa com o seu cliente.

A sua empresa é a responsável pelos dados registrados na confirmação, e a página diz isso à pessoa. Informe em Configurações > Empresa o endereço da sua política de privacidade, para que ela apareça na página.

Nesta página