Pular para o conteúdo

Leads

Um lead é um envio de formulário — um nome, um e-mail, um telefone digitados por uma pessoa real em um formulário do site. São dados pessoais, e esta superfície os trata assim.

Método Caminho Escopo
GET /v1/leads leads:read
GET /v1/leads/{id} leads:read
  • URL base: https://api.canverly.com
  • Autenticação: Authorization: Bearer ck_… — escopo leads:read
  • Limite de requisição: 10 req/min por chave (bucket de leads) e 60 req/min (bucket geral)

O site é derivado da chave. Não existe parâmetro de site, e uma chave só lê os leads do próprio site.

Lista os leads do site, do mais recente para o mais antigo, paginados por cursor.

Parâmetro Tipo Padrão Observações
form_id string (ULID/UUID) — Restringe a um formulário. Omita para listar todos os formulários do site.
status string clean clean, spam ou all. Qualquer outro valor é um 422.
de string — Início do período — YYYY-MM-DD ou um instante RFC-3339.
ate string — Fim do período — inclusivo quando informado como data (ate=2026-08-10 cobre todo o dia 10 de agosto); um instante RFC-3339 explícito é usado como limite superior exclusivo.
cursor string — Cursor keyset vindo do next_cursor da página anterior.
limit integer 50 1–200. Valores fora da faixa são ajustados para dentro dela; um valor não inteiro é rejeitado.
ordem string desc Ordem — desc (mais recentes primeiro) ou asc. Qualquer outro valor é um 422.

de precisa ser estritamente anterior a ate — um período invertido ou vazio é um 422, não uma lista vazia. Uma data ou um cursor que não pode ser interpretado também é um 422: nada é ignorado em silêncio, porque um filtro que cai silenciosamente em um fallback entregaria mais dados pessoais do que você pediu.

Janela do terminal
curl "https://api.canverly.com/v1/leads?status=clean&de=2026-08-01&ate=2026-08-31&limit=50" \
-H "Authorization: Bearer ck_live_xxx"
{
"items": [
{
"id": "01K8Z9K3F7T8M2QYV5N6B4WJ8R",
"form_id": "01K8Z8YVQ4N7B1C2D3E4F5G6H7",
"page_path": "/contato",
"data": {
"nome": "Ana Teste",
"email": "ana@example.test",
"mensagem": "Quero um orçamento."
},
"status": "clean",
"spam_score": 0,
"created_at": "2026-08-24T14:03:11Z"
}
],
"next_cursor": ""
}
Campo Tipo Observações
items[] Lead[] A página de leads — veja o objeto Lead.
next_cursor string | null Devolva-o como cursor para obter a próxima página. O fim da coleção é sinalizado por uma string vazia "" — trate "", null e um campo ausente da mesma forma: pare. Um cursor só é emitido quando a página veio cheia, então a última página sempre encerra a varredura.

Keyset, não offset: leia next_cursor, envie-o como cursor e repita até ele voltar vazio. Cursores são opacos — não os interprete nem os construa. Um cursor de outro filtro não tem significado; mantenha os demais parâmetros idênticos em todas as páginas de uma mesma varredura.

Janela do terminal
curl "https://api.canverly.com/v1/leads?limit=50&cursor=1756044191000000000%7C01K8Z9K3F7T8M2QYV5N6B4WJ8R" \
-H "Authorization: Bearer ck_live_xxx"

Lembre-se do teto de 10 req/min: com limit=200, isso dá até 2 000 leads por minuto, o que basta para uma sincronização, mas não para uma raspagem. Para um dump completo, use a exportação — veja Exportação em massa.

Lê um único lead. id é o ULID do lead (um UUID também é aceito). A resposta é um lead exatamente no mesmo formato de um item da lista — sem o envelope items.

Janela do terminal
curl "https://api.canverly.com/v1/leads/01K8Z9K3F7T8M2QYV5N6B4WJ8R" \
-H "Authorization: Bearer ck_live_xxx"
{
"id": "01K8Z9K3F7T8M2QYV5N6B4WJ8R",
"form_id": "01K8Z8YVQ4N7B1C2D3E4F5G6H7",
"page_path": "/contato",
"data": {
"nome": "Ana Teste",
"email": "ana@example.test"
},
"status": "clean",
"spam_score": 0,
"created_at": "2026-08-24T14:03:11Z"
}
Campo Tipo Observações
id string (ULID) Identificador do lead.
form_id string (ULID) O formulário que o gerou.
page_path string Caminho da página de onde o formulário foi enviado, ex.: /contato.
data object As respostas enviadas: id do campo → valor string. As chaves são os ids de campo do próprio formulário, então variam de formulário para formulário.
status string clean ou spam.
spam_score integer Intensidade do sinal de spam (0 = nenhum sinal).
created_at string (RFC-3339) Quando foi enviado, em UTC.

Tudo em data é digitado por um visitante. Trate como entrada não confiável: escape antes de renderizar e nunca interpole em HTML, SQL ou comando de shell.

Para puxar a coleção inteira de uma vez — NDJSON ou CSV, em streaming — use GET /v1/export?resource=leads em vez de paginar esta rota. Ela exige tanto o escopo export quanto leads:read, e é auditada e tem limite de requisição exatamente como as rotas desta página. Veja Exportação e importação em massa.

Envelope: { "error": { "code", "message" } }. Tabela completa em Erros e limites de requisição.

Status error.code Quando
400 upstream limit malformado na lista (não inteiro). Envie um número inteiro.
401 unauthorized Chave ausente, inválida ou revogada.
403 forbidden A chave não tem leads:read — ele é opt-in, então uma chave que nunca o recebeu cai aqui. Recrie a chave com o escopo.
404 not_found O site não é membro, ou o app Forms não está instalado nele. Em /v1/leads/{id}, também: o lead não existe ou pertence a outro site. Todos esses casos são o mesmo 404 opaco.
422 — Filtro inválido na lista: status desconhecido, ordem desconhecida, de/ate que não pode ser interpretado, período invertido ou cursor malformado. A message diz qual.
429 rate_limited O bucket rígido de leads (10/min) ou o bucket geral (60/min). Respeite o Retry-After.
5xx upstream Erro upstream transitório; tente de novo com backoff.
  • Conceda leads:read a uma chave, para uma tarefa. Uma chave de publicação não precisa dele. Uma chave por consumidor mantém a trilha de auditoria legível e o raio de impacto pequeno.
  • Parta do princípio de que a leitura fica registrada. Toda chamada que você faz é atribuída à chave na trilha de auditoria, inclusive as que terminam em 404.
  • Não espelhe leads em um sistema com controle de acesso mais fraco que o admin do Canverly, e não registre respostas completas em log — isso transforma um log de debug em uma cópia da base de contatos.
  • Faça retries com educação. Em um 429, aguarde Retry-After segundos. A 10 req/min, um ritmo fixo de uma requisição a cada 6 segundos nunca atinge o limite.