Skip to main content
POST
/
api
/
kyc
/
validations
Criar Validação KYC
curl --request POST \
  --url http://api.gu1.ai/api/kyc/validations \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '
{
  "entityId": "<string>",
  "integrationCode": "<string>",
  "doubleCheckRenaper": true,
  "omitWarnings": [
    "<string>"
  ]
}
'
{
  "providerSessionUrl": "<string>",
  "status": "<string>"
}

Resumo

Este endpoint cria uma nova sessão de validação KYC para uma entidade pessoa usando um provedor de integração configurado. Após criar a validação, você receberá uma URL de verificação que pode compartilhar com seu cliente para completar a verificação de identidade.

Diagrama de Fluxo Completo

Sequência desde a criação da entidade até a validação KYC (fluxo de produção; no sandbox com números de documento de teste o passo do provedor é omitido e a API retorna o resultado mock e os webhooks imediatamente—veja Dados mock no sandbox):
1. Entidade e taxId duplicado
  • Crie primeiro a entidade pessoa com POST /api/entities (inclua countryCode). Se o taxId já existir na organização, a API retorna 409 e não cria duplicado; use o ID da entidade existente.
  • Você precisa de um entityId existente para criar uma validação KYC.
2. Código de integração
  • global_gueno_validation_kyc é o código padrão para KYC completo e funciona no sandbox sem configuração adicional.
3. URL de verificação
  • Em produção, a resposta inclui providerSessionUrl. Envie essa URL ao seu usuário; eles completam o fluxo na página do provedor (documento + selfie). A URL é válida até expiresAt.
  • No sandbox, se o documento da entidade estiver na lista de teste, não há sessão do provedor: a API retorna 201 com status pending e momentos depois atualiza a validação e envia os webhooks (ex.: kyc.validation_approved ou kyc.validation_rejected), sem passo do usuário. Importante: Você deve ter um endpoint webhook configurado para receber as respostas - veja Dados mock no sandbox.
4. Eventos de webhook
  • Quando a validação termina, a API envia um webhook à sua URL. O evento é um de: kyc.validation_approved, kyc.validation_rejected, kyc.validation_abandoned, kyc.validation_expired, kyc.validation_cancelled (não um único evento “completed”). O payload é o objeto de validação completo.
  • Você também pode fazer polling em GET /api/kyc/validations/:id para atualizações de status.

Pré-requisitos

Antes de criar uma validação KYC:
  1. A entidade pessoa deve existir: Crie uma entidade pessoa usando a API de Entidades
  2. Integração KYC configurada: Sua organização deve ter um provedor de integração KYC ativado (ex: global_gueno_validation_kyc)
  3. API key válida: Autentique com sua chave API
Sandbox vs Produção: Ambientes sandbox NÃO requerem configuração de perfil ou pré-configuração. Você pode testar validações KYC imediatamente no sandbox com dados de teste. Ambientes de produção requerem:
  • Onboarding da organização concluído
  • Provedor de integração KYC ativado pela equipe gu1
  • Saldo de créditos suficiente para operações KYC
Para começar no sandbox, simplesmente use sua chave de API do sandbox - nenhuma configuração adicional é necessária.

Dados mock (sandbox)

No sandbox, quando o documento da entidade pessoa (taxId) coincide com um dos nossos valores de teste, a API retorna um resultado mock imediato (ex.: aprovado, rejeitado, cancelado) e envia os webhooks correspondentes, sem executar verificação real. O formato do documento não importa (ex.: 99.990.001 e 99990001 funcionam igual). Para a lista completa de números de documento de teste por formato (Argentina DNI/CUIT, Brasil CPF/CNPJ), resultados esperados e exemplos de resposta, veja Dados mock no sandbox.

Comportamentos Importantes

taxId duplicado (POST /entities)

O que acontece se você chamar POST /entities com um taxId que já existe?A API não cria uma segunda entidade. Retorna 409 Conflict com código de erro DUPLICATE_TAX_ID e inclui nos detalhes o id, name e type da entidade existente.O que fazer:
  1. Opção A – Consultar antes: Use GET /api/entities?taxId=12345678 (ou o endpoint by-tax-id) antes de criar. Se a entidade existir, use seu entityId para KYC.
  2. Opção B – Tratar o 409: Se receber 409, leia error.details.existingEntityId na resposta e use esse entityId para sua validação KYC.
  3. Reutilizar a mesma entidade: Use uma entidade por pessoa/empresa e crie várias validações KYC sobre esse mesmo entityId se precisar de re-verificação ou novas tentativas.
Exemplo – Verificar antes de criar:
// Verificar se a entidade existe
const existing = await fetch('https://api.gu1.ai/api/entities?taxId=12345678', {
  headers: { 'Authorization': 'Bearer SUA_API_KEY' }
});
const data = await existing.json();

let entityId;
if (data.data && data.data.length > 0) {
  entityId = data.data[0].id; // Usar entidade existente
} else {
  const createRes = await fetch('https://api.gu1.ai/api/entities', {
    method: 'POST',
    headers: { 'Authorization': 'Bearer SUA_API_KEY', 'Content-Type': 'application/json' },
    body: JSON.stringify({ type: 'person', taxId: '12345678', name: 'João Silva', countryCode: 'AR' })
  });
  const created = await createRes.json();
  entityId = created.entity?.id ?? created.data?.id;
}

// Criar validação KYC com o entityId

Múltiplas Validações KYC por Entidade

Você pode criar múltiplas validações KYC para a mesma entidade:
  • Cada validação recebe um ID e sessão únicos
  • Apenas a validação aprovada mais recente é marcada como isCurrent: true
  • Casos de uso: Re-verificação, validações expiradas, tentativas falhadas

Solicitação

Endpoint

POST https://api.gu1.ai/api/kyc/validations

Headers

{
  "Authorization": "Bearer SUA_API_KEY",
  "Content-Type": "application/json"
}

Parâmetros de Query (opcionais)

doubleCheckRenaper
boolean
Em true, ativa a dupla verificação RENAPER para entidades da Argentina. Em estados terminais a API consulta o registro oficial (dados e, quando aplicável, biometria) e armazena o resultado em metadata. Somente se a verificação OCR KYC retornar o estado approved uma falha no cruzamento pode rejeitar automaticamente a validação; em in_review ou rejected o chequeo é informativo (enforcementApplied: false). Requer entidade da Argentina e credenciais RENAPER configuradas na organização.

Parâmetros do Body

entityId
string
required
O UUID da entidade pessoa a verificarTipo: string (uuid)
integrationCode
string
required
O código do provedor de integração para validação KYCValor Padrão: global_gueno_validation_kyc (recomendado para a maioria dos casos de uso)Tipo: string (comprimento mínimo: 1)
O que é integrationCode?O integrationCode identifica qual integração de provedor KYC usar para verificação. Pense nisso como selecionar o serviço de verificação.Códigos de Integração Disponíveis:
  • global_gueno_validation_kyc - Recomendado - KYC completo com documento + selfie + comparação facial + liveness
  • Códigos personalizados podem ser configurados para sua organização (contate o suporte)
Como encontrar seu código de integração:
  1. Faça login no Dashboard gu1
  2. Navegue até Configurações → Integrações → Provedores KYC
  3. Seu código de integração ativo será listado lá
Em ambientes sandbox, global_gueno_validation_kyc funciona imediatamente sem configuração.
doubleCheckRenaper
boolean
Igual ao query param. Em true ativa a dupla verificação RENAPER para Argentina. Pode ser enviado no body ou como ?doubleCheckRenaper=true. Se ambos forem enviados, o query prevalece.
omitWarnings
string[]
Lista opcional de códigos de aviso KYC (strings exatos). Fica armazenada na validação como metadata.omitWarnings. Ao concluir a sessão, se a validação ficaria em in_review, warnings não está vazio e todos os códigos em warnings aparecem nesta lista, a API define o status como approved e mantém os avisos para UI e auditoria. Se algum aviso não estiver em omitWarnings, o status permanece in_review. Se warnings estiver vazio com status in_review, não há autoaprovação. Códigos inválidos no body retornam 400. Quando a regra se aplica, metadata.kycOmitWarningsApplied registra o instante e os avisos correspondentes.Códigos não omitíveis (ex.: GUENO_CROSS_ENTITY_DUPLICATED) são rejeitados neste campo com 400 e sempre impedem autoaprovação por omit mesmo que constem em warnings.Tipo: string[] (cada elemento deve ser um código permitido; duplicados são ignorados)

Resposta

Resposta Bem-sucedida (201 Created)

{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "entityId": "123e4567-e89b-12d3-a456-426614174000",
  "organizationId": "org_abc123",
  "sessionId": "session_xyz789",
  "status": "pending",
  "provider": "kyc_provider",
  "providerSessionUrl": "https://verify.example.com/session_xyz789",
  "isCurrent": true,
  "metadata": { "doubleChecks": { "renaper": true } },
  "createdAt": "2025-01-15T10:30:00Z"
}
Com dupla verificação RENAPER ativa, em criação é definido metadata.doubleChecks.renaper: true. Após aprovação e execução do chequeo, é preenchido metadata.responseDoubleChecks.renaper (ver Dupla verificação RENAPER).

Campos de Resposta

providerSessionUrl
string
A URL de verificação para compartilhar com seu cliente
status
string
Status atual da validação. Valores possíveis:
  • pending - Validação criada, aguardando o cliente iniciar
  • in_progress - Cliente completando a verificação (preenchendo formulário)
  • in_review - Verificação completa, requer revisão manual da equipe de compliance
  • approved - Verificação bem-sucedida
  • rejected - Verificação falhou
  • expired - Sessão de verificação expirada (ex. após 7 dias)
  • abandoned - Cliente iniciou mas não completou
  • cancelled - Validação cancelada manualmente
Após a aprovação, as chaves de mídia aparecem em decision. Para baixar arquivos (imagens, vídeo), use GET /api/kyc/validations/:id/media?key=... com Authorization: Bearer. Detalhes: Obter mídia da validação KYC.

Exemplo de Solicitação

const response = await fetch('https://api.gu1.ai/api/kyc/validations', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer SUA_API_KEY',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    entityId: '123e4567-e89b-12d3-a456-426614174000',
    integrationCode: 'global_gueno_validation_kyc'
  })
});

const validation = await response.json();
console.log('URL de verificação:', validation.providerSessionUrl);

Dupla verificação RENAPER (Argentina)

Com doubleCheckRenaper: true e entidade da Argentina, em cada estado terminal (approved, rejected, in_review) a API executa verificação cruzada contra o registro oficial (RENAPER) quando há OCR suficiente. Rejeição automática por RENAPER somente se a verificação OCR KYC retornou o estado approved.

Como enviar

  • Body: { "entityId": "...", "integrationCode": "...", "doubleCheckRenaper": true }
  • Query: POST /api/kyc/validations?doubleCheckRenaper=true com o mesmo body. Se ambos forem enviados, o query prevalece.

Onde o resultado é armazenado

Em metadata.responseDoubleChecks.renaper. Códigos de mismatch (ex.: trâmite e vencimento) são adicionados a metadata.warnings sem substituir avisos anteriores da verificação OCR KYC. errorCode no objeto renaper mantém a primeira falha por compatibilidade; a UI pode listar todos os códigos em comparisonResults e warnings. Campos de metadata.responseDoubleChecks.renaper:
CampoTipoDescrição
verifiedbooleantrue se o chequeo passou.
matchResultstring"match" | "mismatch" | "error".
verifiedAtstringTimestamp ISO do chequeo.
personalNumberstringNúmero de trâmite do KYC.
idTramitePrincipalstringNúmero de trâmite do RENAPER.
renaperDataobjectResposta bruta do RENAPER (ver forma de renaperData).
comparisonResultsobjectComparação campo a campo entre OCR e registro (quando aplicável).
renaperBiometricobjectResultado biométrico ABIS (validate-dni): matchResult, score, renaperData (resposta bruta).
errorCodestringPresente se falhou; ver códigos abaixo.

Forma de renaperData

É o body sem transformação retornado pelo registro via ms-providers (POST …/provider-records/renaper/data). A Gu1 repassa como está em metadata.responseDoubleChecks.renaper.renaperData. Os nomes dos campos estão em snake_case; todos são opcionais conforme o retorno do RENAPER em cada consulta. Exemplo (dupla verificação bem-sucedida, matchResult: "match"):
{
  "id_tramite_principal": "987654321",
  "id_tramite_tarjeta_reimpresa": "112233445",
  "ejemplar": "A",
  "vencimiento": "2030-05-20",
  "emision": "2015-05-20",
  "apellido": "García",
  "nombres": "Juan",
  "fecha_nacimiento": "1990-01-15",
  "cuil": "20-30123456-9",
  "calle": "Av. Corrientes",
  "numero": "1234",
  "piso": "5",
  "departamento": "B",
  "codigo_postal": "1043",
  "barrio": "San Nicolás",
  "monoblock": "",
  "ciudad": "Ciudad Autónoma de Buenos Aires",
  "municipio": "Comuna 1",
  "provincia": "Buenos Aires",
  "pais": "Argentina",
  "nacionalidad": "Argentina",
  "codigo_fallecido": "",
  "mensaje_fallecido": "",
  "fecha_fallecimiento": "",
  "id_ciudadano": "30123456",
  "codigo": "",
  "mensaje": ""
}
Outros casos comuns:
SituaçãorenaperData típico
Erro antes de obter dados (ex.: RENAPER_DNI_MISSING){}
Serviço indisponível (RENAPER_VERIFICATION_UNAVAILABLE){ "error": "…", "code": "SERVICE_UNAVAILABLE" }
Cruzamento falhou com payload parcial do registroSubconjunto de campos (ex.: id_tramite_principal, apellido, nombres, fecha_nacimiento)
No sandbox, os mesmos valores mock aparecem em Dados mock de KYC (sandbox).

Forma de comparisonResults

Mapa por campo (dni, tramite, name, ejemplar, dateOfBirth, expirationDate). Cada entrada pode incluir:
CampoTipoDescrição
comparedbooleantrue se a comparação foi tentada; false se omitida por dados faltantes.
passedbooleanResultado quando compared é true.
skipReasonstringocr_missing, renaper_missing ou both_missing quando não comparado.
ocrValuestringValor extraído do OCR (se aplicável).
renaperValuestringValor do registro RENAPER (se aplicável).
similarityPercentnumberApenas em name: similaridade Levenshtein (0–100).
thresholdnumberApenas em name: limiar aplicado (ex.: 80).
errorCodestringCódigo de falha do campo (ex.: RENAPER_DNI_NOT_MATCH).
Para ejemplar, o valor OCR é extractedData.ejemplar (ver campos de extractedData). A comparação ocorre quando existem ambos os valores OCR e RENAPER. Exemplo — extractedData numa validação KYC aprovada (Argentina):
"extractedData": {
  "documentNumber": "38966181",
  "personalNumber": "00460759387",
  "taxNumber": "20389661814",
  "ejemplar": "C",
  "dateOfBirth": "1995-05-22",
  "expirationDate": "2031-10-17",
  "nationality": "ARG"
}

Forma de renaperBiometric

Objeto aninhado em metadata.responseDoubleChecks.renaper.renaperBiometric quando a org tem credenciais biométricas e a sessão KYC fornece selfie. O Gu1 envia uma selfie a validate-dni; o RENAPER compara com a foto do documento no registro.
CampoTipoDescrição
verifiedbooleantrue quando resultado.match do chequeo biométrico ABIS é positivo.
matchResultstring"match" | "mismatch" | "error".
scorenumberPontuação do chequeo biométrico (se aplicável).
verifiedAtstringTimestamp ISO do chequeo biométrico.
renaperDataobjectResposta bruta de validate-dni (inclui resultado.match, resultado.score, etc.).
submittedSelfieRefstringReferência da selfie enviada: caminho de armazenamento (kyc/...) ou URL (https://...).
submittedSelfieRefKindstringFormato de submittedSelfieRef: s3_key (caminho interno) | url (URL pública).
submittedSelfiePickedFromstringOrigem em decision: liveness_reference_image ou face_match_target_image.
errorCodestringSe falhar (ex.: RENAPER_BIOMETRIC_NOT_MATCH).
skipReasonstringSe não executado (ex.: selfie indisponível).

Exemplo completo de responseDoubleChecks.renaper

{
  "verified": true,
  "matchResult": "match",
  "personalNumber": "00123456789",
  "idTramitePrincipal": "987654321",
  "verifiedAt": "2026-06-05T14:30:00.000Z",
  "enforcementApplied": true,
  "renaperData": {
    "id_tramite_principal": "987654321",
    "apellido": "García",
    "nombres": "Juan",
    "fecha_nacimiento": "1990-01-15",
    "ejemplar": "A",
    "vencimiento": "2030-05-20"
  },
  "comparisonResults": {
    "dni": {
      "field": "dni",
      "compared": true,
      "passed": true,
      "ocrValue": "30123456",
      "renaperValue": "30123456"
    },
    "tramite": {
      "field": "tramite",
      "compared": true,
      "passed": true,
      "ocrValue": "00123456789",
      "renaperValue": "987654321"
    },
    "name": {
      "field": "name",
      "compared": true,
      "passed": true,
      "ocrValue": "Juan García",
      "renaperValue": "García Juan",
      "similarityPercent": 92,
      "threshold": 80
    },
    "ejemplar": {
      "field": "ejemplar",
      "compared": true,
      "passed": true,
      "ocrValue": "A",
      "renaperValue": "A"
    },
    "dateOfBirth": {
      "field": "dateOfBirth",
      "compared": true,
      "passed": true,
      "ocrValue": "1990-01-15",
      "renaperValue": "1990-01-15"
    }
  },
  "renaperBiometric": {
    "verified": true,
    "matchResult": "match",
    "score": 0.91,
    "verifiedAt": "2026-06-05T14:30:02.000Z",
    "submittedSelfieRef": "kyc/org-id/entity-id/session-id/selfie.jpg",
    "submittedSelfieRefKind": "s3_key",
    "submittedSelfiePickedFrom": "liveness_reference_image",
    "renaperData": {
      "resultado": {
        "match": true,
        "score": 0.91
      }
    }
  }
}
renaperBiometric e entradas em comparisonResults podem ser omitidos conforme credenciais, dados OCR ou disponibilidade de selfie.

Códigos de erro (quando RENAPER falha)

O motivo da rejeição é um código em metadata.warnings e em metadata.responseDoubleChecks.renaper.errorCode. A UI deve traduzir esses códigos.
CódigoSignificado
RENAPER_DNI_MISSINGNúmero de documento (DNI) não obtido na verificação.
RENAPER_GENDER_MISSINGGénero (M/F) obrigatório para chamar RENAPER.
RENAPER_VERIFICATION_UNAVAILABLENão foi possível completar a verificação cruzada (ex.: rede). Tente novamente.
RENAPER_DNI_NOT_MATCHO número do documento não coincide com o registro oficial.
RENAPER_TRAMITE_DATA_MISSINGFaltam dados para comparar o número de trâmite.
RENAPER_TRAMITE_ID_NOT_MATCHO número de trâmite do documento não coincide com o registro (exemplar antigo, vencido ou reemitido; a pessoa deve verificar novamente com documento vigente).
RENAPER_NAME_NOT_MATCHO nome do OCR está abaixo do limiar de 80% de similaridade com o registro RENAPER.
RENAPER_EJEMPLAR_NOT_MATCHO exemplar do documento não coincide com o registro RENAPER.
RENAPER_DOB_NOT_MATCHA data de nascimento do OCR não coincide com o registro RENAPER.
RENAPER_EXPIRY_NOT_MATCHA data de vencimento do OCR não coincide com o registro RENAPER.
RENAPER_BIOMETRIC_NOT_MATCHA selfie não coincide com a foto do documento no registro biométrico.
RENAPER_BIOMETRIC_UNAVAILABLENão foi possível completar o chequeo biométrico (rede, credenciais ou serviço).

Quando o RENAPER aplica enforce (rejeição automática)

Estado da verificação OCR KYCRENAPER executa?Pode rejeitar por RENAPER?
approved (aprovação direta)SimSim — falha no cruzamento → rejected
in_reviewSimNão — informativo; equipe decide na revisão manual
rejected (verificação OCR ou regras Gu1)Sim (se houver OCR)Não — informativo; dados ficam em metadata
Aprovação manual a partir de in_review (POST …/approve)Não (reutiliza chequeo salvo)Não — decisão humana
Em todos os casos com consulta ativa, dados e biometria ficam em metadata.responseDoubleChecks.renaper. Em in_review e rejected, códigos RENAPER com mismatch são adicionados a warnings junto com avisos da verificação OCR.

Próximos Passos

Depois que a validação for approved, leia as chaves em decision e baixe os arquivos — veja Obter mídia da validação KYC.

Obter URL de KYC

Aprenda como recuperar a URL

Integração Webhook

Configure notificações webhook