Versão 2026-09-23
Mudança aditiva — nenhuma integração existente quebra.Novo: Verificação Facial (Face Match + Passive Liveness)
- Novo endpoint
POST /verificacoes/facial— verificação facial avulsa, sem vincular a um cliente cadastrado. Requer novo escopobiometria:write. Ver Verificação facial avulsa. POST /customers(via upload de documentos em sequência) ePOST /customers/{id}/documentspassam a disparar Face Match + Passive Liveness automaticamente, em background, quando o par selfie + documento de identidade suportado fica completo — condicionado a módulo “Verificação facial” ativo (master) e configuração habilitada (tenant); sem parâmetro para ativar/pular por chamada. Ver Criar cliente e Anexar documento.GET /api/v1/customers/:idganha o campofacial_verification— resultado da rodada mais recente, apenas para clientes PF.- Novo evento de webhook
biometric_check.completed— disparado ao final de cada rodada de verificação facial do fluxo automático (não do endpoint avulso, que é síncrono). Requer marcar o evento em “Eventos assinados” na configuração do endpoint — diferente derun.completed/run.failed, que são sempre entregues. - Verificação facial bem-sucedida consome o mesmo saldo do tenant usado por bureau runs.
- Visão geral do produto, os dois fluxos disponíveis e a pendência jurídica de LGPD em aberto: Verificação Facial.
Versão 2026-08-27
Mudança aditiva — nenhuma integração existente quebra.addressemPOST /api/v1/customerse na resposta deGET /api/v1/customers/:idpassa a validar formato:street,city(não vazias, com limite de tamanho),numberecomplement(limite de tamanho),state(sigla de UF válida, antes só checava 2 caracteres) ezip(8 dígitos após remover não-dígitos). Payloads já corretos não são afetados; payloads com dado inválido nesses campos passam a retornar400 invalid_address.- Novos subcampos opcionais em
address:complementeneighborhood. GET /api/v1/customers/:idagora retornaaddresspara clientes PJ além de PF (antes só retornava para PF, mesmo quando o endereço PJ existia salvo).
email/phone na listagem de clientes
GET /api/v1/customers(listagem) passa a incluiremailephoneem cada item dedata[]— colunas simples da mesma tabela, sem join, sem custo extra de query. Mesma regra de mascaramento de e-mail-placeholder já usada emGET /customers/:id(cliente PJ sem e-mail real não expõe o endereço@kycert.internalgerado internamente).documentselatest_runcontinuam exclusivos deGET /customers/:id— cada um exigiria uma query por cliente numa listagem (N+1). Decisão deliberada, não uma lacuna. Ver Listar clientes, seção “Campos ausentes na listagem”.POST /api/v1/customerstambém passa a retornarphonena resposta de criação quando enviado no payload (já era aceito e persistido, mas não voltava na resposta).
Novo endpoint: anexar documento
POST /customers/{id}/documents(multipart/form-data) — anexa um documento (RG, CNH, comprovante de residência etc.) a um cliente já cadastrado. Reusa o escopocustomers:write, sem escopo novo. Limite de arquivo: 4MB (teto de infraestrutura da plataforma de hosting, não configurável). Ver Anexar documento.GET /api/v1/customers/:idganha o campodocuments— resumo (type,status,created_at) dos documentos anexados ao cliente, semstorage_pathnem signed URL.
template_id agora é opcional em run_bureau: true
POST /customerscomrun_bureau: truenão exige maistemplate_idquando o tenant tem um template padrão configurado em Configurações → Bureau (PF e/ou PJ) — a API resolve automaticamente pelotypedo cliente. Ver Criar cliente, seção “Template padrão”.- Novo campo opcional
onboarding_profile(slug) — quando enviado e válido, o template do perfil de cadastro tem prioridade sobre o default do tenant, mesma prioridade do?perfil=slugdo portal público. - Chamadas com
template_idexplícito continuam funcionando exatamente como antes — nenhuma mudança de comportamento ou resposta para quem já enviatemplate_id. - Atenção — mudança de código de erro: chamadas com
run_bureau: truesemtemplate_ide sem template padrão configurado, que antes retornavam400 missing_template_id, agora retornam400 missing_default_template(mensagem orienta a configurar um default ou enviartemplate_id). Se sua integração faz match programático noerror.codemissing_template_id, atualize paramissing_default_template. - O toggle “Bureau automático” (
bureau_enabled) do dashboard, que controla o disparo automático do portal público, não afeta esta resolução —run_bureau: truevia API é sempre um pedido explícito do integrador.
Campos complementares em POST /customers e GET /customers/:id
- Novos campos opcionais:
nationality,occupation,declared_income(PF) etrade_name,annual_revenue,business_activity,employee_count(PJ) — mesmos dados que o portal público de cadastro já coleta, agora disponíveis para fechar um cadastro completo via API. Ver Criar cliente. - Cada campo é exclusivo do
typecorrespondente — enviar um campo PF comtype: "pj"(ou vice-versa) retorna400 invalid_request_error. declared_incomeeannual_revenuesão apenas armazenados — não acionam recálculo automático de capacidade financeira (motor de renda).GET /api/v1/customers/:idretorna cada campo apenas quando foi enviado na criação — nenhum valor default é inventado.
Novo header: Idempotency-Key em POST /customers
POST /api/v1/customerspassa a suportar o headerIdempotency-Key(mesmo mecanismo já usado porPOST /bureau/runs) — envie um UUID único por tentativa; reenviar a mesma chave nas próximas 24h retorna a resposta original em cache, sem criar cliente nem disparar bureau de novo. Ver Criar cliente, seção “HeaderIdempotency-Key”.- Corrige um bug de produção: retry sem essa chave num cliente que já existia em
rascunho(de um convite/formulário incompleto do portal) disparava um segundo bureau run para o mesmo cliente a cada tentativa, cobrado em dobro. O header é opcional (opt-in) — chamadas sem ele continuam funcionando exatamente como hoje. - Correção pós-QA: a primeira versão fechava a janela só para retries sequenciais — duas chamadas com a mesma
Idempotency-Keydisparadas em paralelo (ex: timeout de rede curto + retry automático) ainda podiam ambas passar e duplicar o bureau run. Agora a chave é reservada atomicamente na primeira chamada: uma segunda chamada concorrente enquanto a primeira ainda processa recebe409 idempotency_key_in_progress(com headerRetry-After) em vez de reprocessar. Novo código de erro, mudança aditiva.
Versão 2026-06-03
Versão inicial pública da API kycert.Endpoints disponíveis
POST /api/v1/bureau/runs— criar run de bureauGET /api/v1/bureau/runs— listar runs com filtros e paginaçãoGET /api/v1/bureau/runs/:id— obter status e resultado de um runGET /api/v1/bureau/runs/:id/analysis— análise completa com todos os checksGET /api/v1/bureau/runs/:id/detail— detalhe técnico por fonte (escopodetail:read)
Autenticação
- Header
x-api-key: sk_live_...(recomendado) - Header
Authorization: Bearer sk_live_...(alternativo) - Escopos:
runs:write,runs:read,detail:read
Webhooks
- Evento
run.completed— run finalizado com decisão - Evento
run.failed— falha técnica no run - Verificação de assinatura HMAC-SHA256 via header
kycert-signature - Política de retry: 7 tentativas em até 24h
Outros
Idempotency-KeynoPOST /runs— retry seguro nas próximas 24hx-kycert-api-version— versionamento explícito- Sandbox com CPFs e CNPJs de teste
- Paginação cursor-based no
GET /runs
Política de breaking changes
Nos comprometemos com estabilidade. Antes de qualquer breaking change:- Aviso mínimo de 90 dias — comunicado por e-mail e no dashboard
- Headers de deprecação — respostas incluirão
DeprecationeSunsetquando um endpoint ou campo for depreciado - E-mail de aviso — clientes com keys ativas na versão depreciada recebem notificação
- Versão antiga mantida por no mínimo 12 meses após o anúncio de depreciação
O que é considerado breaking change
- Remover ou renomear um campo de response
- Alterar o tipo de um campo existente
- Remover um endpoint
- Alterar o comportamento de um código de erro existente
- Remover um valor de enum existente
O que não é breaking change
- Adicionar novos campos opcionais ao request ou response
- Adicionar novos endpoints
- Adicionar novos valores de enum
- Melhorar mensagens de erro
- Mudanças de performance ou latência