Riv.IA EYE API
Verificação visual de identidade via API REST. Um único endpoint executa qualquer combinação de checks sobre a mesma imagem, autenticado por Bearer Token.
- Produção
- https://api.riv.ia.br
- Dev
- https://dev.riv.ia.br
Como usar a API
Todos os endpoints exigem um Bearer Token. Gere o token primeiro e inclua-o no header de cada requisição.
- 1
Gerar token
Autentique com client_id e client_secret para receber o Bearer Token.
- 2
Enviar imagem
Faça POST em /eye/v1/verify com a imagem e os checks desejados.
- 3
Receber veredito
Resposta JSON explicável com o veredito agregado approved.
Precisa de credenciais? Para obter seu client_id e client_secret, entre em contato pelo email contato@riviadev.com.br.
Autenticação
Use suas credenciais para gerar um Bearer Token de curta duração. Inclua-o no header Authorization: Bearer <token> em todas as chamadas subsequentes.
/auth/v1/tokens/generateTroca suas credenciais por um Bearer Token de acesso.
Body (application/json)
client_idstringobrigatório- Identificador do cliente fornecido pela RiviaDev.
client_secretstringobrigatório- Segredo do cliente. Mantenha-o seguro — nunca exponha em código client-side.
curl -X POST https://api.riv.ia.br/auth/v1/tokens/generate \ -H "Content-Type: application/json" \ -d '{"client_id":"SEU_CLIENT_ID","client_secret":"SEU_CLIENT_SECRET"}'
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR...",
"token_type": "Bearer",
"expires_in": 3600
}Endpoint /verify
Ponto de entrada único para verificação visual. Combine os checks que precisar em checks — o veredito approved é a conjunção de todos os checks solicitados.
/eye/v1/verifylivenessProva de vidaselfieface_matchComparação facialselfie+documentauthenticityAutenticidade / anti-spoofselfieelement_detectionDetecção de elementosselfie+detection_requesttext_extractionExtração de textoselfie+extraction_requestqr_codeLeitura de QR codeselfie(+extraction_requestopcional)document_extractiondevExtração de documentodocument(semselfie)
Headers
Authorizationstringobrigatório- Bearer Token obtido em
/auth/v1/tokens/generate. Formato:Bearer <token>.
Body (multipart/form-data)
checksstringobrigatório- Lista de checks a executar, separados por vírgula:
liveness,face_match,authenticity,element_detection,text_extraction,qr_code,document_extraction. selfiefile- Imagem a verificar: a selfie da pessoa ou, no
qr_code, a foto com o QR code. Formatos: JPG, JPEG, PNG, GIF, BMP, WEBP, DNG (máx. 10MB). Obrigatório com todos os checks, exceto quando sódocument_extractioné pedido. documentfile- Imagem do documento. Obrigatório com
face_matchedocument_extraction. Nodocument_extractionaceita também PDF de 1 página. detection_requeststring (JSON)- JSON com os elementos a detectar. Obrigatório com
element_detection. extraction_requeststring (JSON)- JSON com os campos de texto a ler. Obrigatório com
text_extraction; opcional comqr_code, onde liga o fallback para OCR.
Resposta
Todo check pedido vem como um objeto com o próprio nome; os não pedidos vêm como null. O schema de cada objeto está na seção do check.
successboolean- Indica se a chamada foi processada com sucesso.
approvedboolean- Veredito agregado: true quando todos os checks solicitados passaram.
checksstring[]- Lista dos checks efetivamente executados, na ordem.
<check>object | null- Resultado de cada check pedido.
nullpara os não pedidos. messagestring | null- Mensagem complementar legível sobre o resultado.
Vários checks em uma chamada
Combine os checks no mesmo request — eles rodam em paralelo.
curl -X POST https://api.riv.ia.br/eye/v1/verify \ -H "Authorization: Bearer $RIVIA_KEY" \ -F "selfie=@selfie.jpg" \ -F "document=@rg.jpg" \ -F 'detection_request={"elements":[{"type":"object","description":"crachá","required":true}]}' \ -F "checks=liveness,face_match,authenticity,element_detection"
{
"success": true,
"approved": true,
"checks": ["liveness", "face_match", "authenticity", "element_detection"],
"liveness": { "resultado": true, "confidence": 0.93, ... },
"face_match": { "same_person": true, "confidence": 0.88, ... },
"authenticity": { "is_authentic": true, "confidence": 0.9, ... },
"element_detection": { "all_required_found": true, ... },
"message": "Verificação aprovada"
}Checks
livenessProva de vida
Verifica se a imagem é uma selfie real de uma pessoa viva — não uma foto de tela, impressa ou gerada por IA.
Enviar: checks=liveness + selfie
Objeto liveness
resultadoboolean- true quando a imagem é uma selfie real de um ser humano. É o que entra no
approved. person_presentboolean | null- Se há uma pessoa física na imagem.
confidencefloat | null- Confiança do veredito.
detalhesstring[]- Motivos da reprovação. Vazio quando aprovado.
authenticityobject | null- Veredito anti-spoof calculado na mesma inferência. Mesmo schema do check
authenticity.
Comportamento
- Pedir
livenessjunto comauthenticityconsome uma única inferência: o resultado anti-spoof é reaproveitado.
Selfie real de uma pessoa viva.
curl -X POST https://api.riv.ia.br/eye/v1/verify \ -H "Authorization: Bearer $RIVIA_KEY" \ -F "selfie=@selfie.jpg" \ -F "checks=liveness"
{
"success": true,
"approved": true,
"checks": ["liveness"],
"liveness": {
"resultado": true,
"person_present": true,
"confidence": 0.93,
"detalhes": [],
"authenticity": { "is_authentic": true, ... }
},
"message": "Verificação aprovada"
}face_matchComparação facial
Compara o rosto da selfie com a foto do documento e diz se são da mesma pessoa.
Enviar: checks=face_match + selfie + document
Objeto face_match
same_personboolean- true quando selfie e documento são da mesma pessoa.
confidencefloat- Confiança da comparação, de 0 a 1.
detailsstring[]- Detalhes estruturais da análise (olhos, nariz, contorno).
Comportamento
- Sem
documenta API responde422.
Selfie e documento da mesma pessoa.
curl -X POST https://api.riv.ia.br/eye/v1/verify \ -H "Authorization: Bearer $RIVIA_KEY" \ -F "selfie=@selfie.jpg" \ -F "document=@rg.jpg" \ -F "checks=face_match"
{
"success": true,
"approved": true,
"checks": ["face_match"],
"face_match": {
"same_person": true,
"confidence": 0.88,
"details": ["Estrutura facial compatível."]
},
"message": "Verificação aprovada"
}authenticityAutenticidade / anti-spoof
Detecta foto de tela, foto impressa ou imagem gerada por IA. Funciona para qualquer imagem, com pessoa ou objeto.
Enviar: checks=authenticity + selfie
Objeto authenticity
is_authenticboolean- true quando a imagem não é spoof.
is_screen_photoboolean- Foto de tela ou monitor.
is_printed_photoboolean- Foto de material impresso.
is_ai_generatedboolean- Imagem gerada por IA.
confidencefloat- Confiança do veredito.
signalsstring[]- Sinais estruturais observados (ex.: moiré, grade de pixels, borda do monitor).
reasonsstring[]- Justificativa legível do veredito.
Comportamento
- Reflexo e brilho sozinhos nunca classificam a imagem como foto de tela: são precisos ao menos 2 artefatos estruturais.
Sem evidência de spoof.
curl -X POST https://api.riv.ia.br/eye/v1/verify \ -H "Authorization: Bearer $RIVIA_KEY" \ -F "selfie=@selfie.jpg" \ -F "checks=authenticity"
{
"success": true,
"approved": true,
"checks": ["authenticity"],
"authenticity": {
"is_authentic": true,
"is_screen_photo": false,
"is_printed_photo": false,
"is_ai_generated": false,
"confidence": 0.9,
"signals": [],
"reasons": ["Sem evidência de spoof."]
},
"message": "Verificação aprovada"
}element_detectionDetecção de elementos
Verifica se elementos esperados estão na imagem: roupas, acessórios, objetos, textos, logos, cores ou pessoas.
Enviar: checks=element_detection + selfie + detection_request
detection_requeststring (JSON)obrigatório- Até 5 elementos.
type:clothing,accessory,object,text,logo,color_schemeouperson.expected_count(1–10) é opcional, útil para pessoas. Ex.:{"elements":[{"type":"object","description":"crachá","required":true}]}.
Objeto element_detection
all_required_foundboolean- true quando todos os elementos obrigatórios foram encontrados.
detection_summarystring- Resumo legível da análise.
detected_elementsobject[]- Resultado de cada elemento pedido. Schema abaixo.
blocked_by_authenticityboolean- true quando a lista veio vazia porque a imagem reprovou no gate anti-spoof, e não por falha na detecção.
Cada item de detected_elements
typestring- Tipo do elemento pedido.
descriptionstring- Descrição do elemento pedido.
foundboolean- Se o elemento foi encontrado.
confidencefloat- Confiança da detecção.
detailsstring- Detalhes sobre a detecção ou a ausência.
quantity_foundinteger | null- Quantidade encontrada, quando
expected_countfoi enviado.
Comportamento
- Sem
detection_requesta API responde422. - A detecção passa pelo gate anti-spoof mesmo sem pedir
authenticity.
Crachá obrigatório encontrado.
curl -X POST https://api.riv.ia.br/eye/v1/verify \ -H "Authorization: Bearer $RIVIA_KEY" \ -F "selfie=@selfie.jpg" \ -F 'detection_request={"elements":[{"type":"object","description":"crachá","required":true}]}' \ -F "checks=element_detection"
{
"success": true,
"approved": true,
"checks": ["element_detection"],
"element_detection": {
"all_required_found": true,
"detection_summary": "Crachá detectado na imagem.",
"detected_elements": [{
"type": "object",
"description": "crachá",
"found": true,
"confidence": 0.92,
"details": "Crachá visível no peito.",
"quantity_found": null
}],
"blocked_by_authenticity": false
},
"message": "Verificação aprovada"
}text_extractionExtração de texto
Lê campos de texto específicos da imagem, como um código impresso numa etiqueta, com validação opcional de formato.
Enviar: checks=text_extraction + selfie + extraction_request
extraction_requeststring (JSON)obrigatório- Até 5 campos.
expected_formaté uma regex RE2 opcional (full match; sem backreference nem lookaround). Ex.:{"fields":[{"name":"codigo_bag","description":"código impresso abaixo do QR","expected_format":"^[A-Z]{3}[0-9]{5}$","required":true}]}.
Objeto text_extraction
all_required_foundboolean- true quando todos os campos obrigatórios foram lidos e validados.
extraction_summarystring- Resumo legível da extração.
extracted_fieldsobject[]- Resultado de cada campo pedido. Schema abaixo.
blocked_by_authenticityboolean- true quando a lista veio vazia porque a imagem reprovou no gate anti-spoof, e não por falha na leitura.
Cada item de extracted_fields
namestring- Nome do campo pedido.
valuestring | null- Texto lido.
nullquando não foi lido. foundboolean- Se o valor foi lido e, havendo formato, validado.
confidencefloat- Confiança da leitura.
matches_formatboolean | null- Se o valor casou com o
expected_format.nullquando não há formato. detailsstring- Detalhes sobre a leitura ou a ausência.
Comportamento
- Sem
extraction_request, ou com JSON inválido, a API responde422. - A leitura passa pelo gate anti-spoof mesmo sem pedir
authenticity.
Campo lido e validado pelo formato.
curl -X POST https://api.riv.ia.br/eye/v1/verify \ -H "Authorization: Bearer $RIVIA_KEY" \ -F "selfie=@bag.jpg" \ -F 'extraction_request={"fields":[{"name":"codigo_bag","description":"código impresso abaixo do QR","expected_format":"^[A-Z]{3}[0-9]{5}$","required":true}]}' \ -F "checks=text_extraction"
{
"success": true,
"approved": true,
"checks": ["text_extraction"],
"text_extraction": {
"all_required_found": true,
"extraction_summary": "Código lido abaixo do QR.",
"extracted_fields": [{
"name": "codigo_bag",
"value": "ABC12345",
"found": true,
"confidence": 0.95,
"matches_format": true,
"details": "Código impresso legível."
}],
"blocked_by_authenticity": false
},
"message": "Verificação aprovada"
}qr_codeLeitura de QR code
Lê o QR code da foto. Com extraction_request, lê o código impresso quando o QR falta, está ilegível ou vem vazio.
Enviar: checks=qr_code + selfie (+ extraction_request opcional)
Objeto qr_code
foundboolean- true quando um valor foi lido e, se houver
expected_format, casou com ele. valuestring | null- Texto lido do QR ou do OCR.
nullquando não há leitura válida. source"qr" | "ocr" | null- Origem do valor.
status"read" | "ocr_fallback" | "not_found"read: lido do QR.ocr_fallback: lido pelo OCR porque não havia QR legível.not_found: nada válido foi lido.confidencefloat | null- Confiança da leitura.
1.0no caminho QR — o decode é validado por Reed-Solomon, então ou sai o valor gravado ou não sai nada. No fallback, a confiança do campo lido pelo OCR.nullquando nada foi lido. matches_formatboolean | null- Se o valor casou com o
expected_format.nullquando não há formato. Um QR lido que não casa com o formato retornanot_foundcommatches_format=false, sem acionar o OCR. qr_countinteger- Quantidade de QR codes com texto detectados na foto. Com mais de um, vale o de maior área.
detailsstring- Motivo legível da leitura (ex.: QR sem texto, timeout na decodificação, DNG lido direto pelo OCR). Texto livre: não use em lógica.
blocked_by_authenticityboolean- true quando a imagem foi reprovada no gate anti-spoof (foto de tela, impressa ou gerada por IA). Nesse caso
found=false,value=nullestatus=not_found.
Comportamento
approvedexige código lido e imagem autêntica — a leitura passa pelo gate anti-spoof mesmo sem pedirauthenticity.- Nada lido é
200comapproved=falseestatus=not_found, não400. - Arquivos DNG vão direto para o OCR, então só são lidos com
extraction_request.
Com vários QRs, vale o de maior área. Sem extraction_request não há fallback.
curl -X POST https://api.riv.ia.br/eye/v1/verify \ -H "Authorization: Bearer $RIVIA_KEY" \ -F "selfie=@bag.jpg" \ -F "checks=qr_code"
{
"success": true,
"approved": true,
"checks": ["qr_code"],
"qr_code": {
"found": true,
"value": "ABC12345",
"source": "qr",
"status": "read",
"confidence": 1.0,
"matches_format": null,
"qr_count": 2,
"details": "QR code lido",
"blocked_by_authenticity": false
},
"message": "Verificação aprovada"
}document_extractiondevExtração de documento
Identifica se a imagem é um documento e, sendo RG ou CNH, devolve os campos extraídos com confiança por campo.
Enviar: checks=document_extraction + document (sem selfie)
documentfileobrigatório- Imagem JPEG, PNG ou WebP, ou PDF de 1 página (ex.: CNH digital exportada da Carteira Digital de Trânsito), até 10MB. Uma face por chamada — frente ou verso; a CNH digital traz as duas na mesma página.
Objeto document_extraction
type"rg" | "cnh" | "not_a_document" | "unsupported_document" | "unreadable_document"rgecnhaprovam.not_a_document,unsupported_document(ex.: passaporte, CRLV, diploma) eunreadable_documentreprovam:approved=false,fields=nullemessageexplica o motivo.model"legacy" | "cin" | "physical" | "digital" | null- Modelo do documento:
legacyoucinpara RG,physicaloudigitalpara CNH.nullquando indeterminado. side"front" | "back" | "both" | null- Face enviada:
front,backouboth.nullquando indeterminado. classification_confidencefloat- Confiança da classificação do tipo do documento.
fieldsobject | null- Campos extraídos, cada um como
{value, confidence}. Todas as chaves do tipo sempre vêm; campo não legível vem{value: null, confidence: 0}— nunca um valor inventado, então cabe a você decidir o que vai para revisão humana.nullnos tipos de rejeição. messagestring | null- Motivo da rejeição.
nullquando o documento é RG ou CNH.
Campos por tipo
rgtype = "rg"numero_rg,orgao_expedidor,uf_expedidor,data_expedicao,nome,data_nascimento,filiacao_1,filiacao_2,naturalidade,cpf.cnhtype = "cnh"numero_registro,nome,data_nascimento,filiacao_1,filiacao_2,cpf,doc_identidade_numero,doc_identidade_orgao,doc_identidade_uf,categoria,data_primeira_habilitacao,data_emissao,validade,local_emissao,observacoes.valuestring | null- Datas em
YYYY-MM-DD. CPF no formato000.000.000-00, validado pelo dígito verificador. Nomes sem acento e em maiúsculas. Filiação na ordem impressa, sem distinguir pai e mãe.
Comportamento
- Rejeição também é
200, comapproved=false. - Combinável:
liveness,face_match,document_extractionfaz o KYC completo em uma chamada — aí aselfievolta a ser obrigatória. - Não há retenção: a imagem e os campos extraídos não são armazenados nem logados.
- Sem
documenta API responde422; PDF com mais de 1 página responde400.
Verso de RG. Campo não legível vem com value null e confidence 0.Disponível só no ambiente dev enquanto está em validação; ainda não está em produção.
curl -X POST https://dev.riv.ia.br/eye/v1/verify \ -H "Authorization: Bearer $RIVIA_KEY" \ -F "document=@rg_verso.jpg" \ -F "checks=document_extraction"
{
"success": true,
"approved": true,
"checks": ["document_extraction"],
"document_extraction": {
"type": "rg",
"model": "legacy",
"side": "back",
"classification_confidence": 0.96,
"fields": {
"numero_rg": { "value": "12.345.678-9", "confidence": 0.95 },
"orgao_expedidor": { "value": "SSP", "confidence": 0.94 },
"uf_expedidor": { "value": "SP", "confidence": 0.96 },
"data_expedicao": { "value": "2015-03-12", "confidence": 0.93 },
"nome": { "value": "MARIA DA SILVA", "confidence": 0.97 },
"data_nascimento": { "value": "1990-07-04", "confidence": 0.96 },
"filiacao_1": { "value": "JOSE DA SILVA", "confidence": 0.92 },
"filiacao_2": { "value": null, "confidence": 0.0 },
"naturalidade": { "value": "SAO PAULO-SP", "confidence": 0.9 },
"cpf": { "value": "123.456.789-09", "confidence": 0.95 }
},
"message": null
},
"message": "Verificação aprovada"
}Códigos de status
200OK- Verificação processada. Reprovação de negócio também é 200 com
approved=false. 400Bad Request- Parâmetros inválidos, arquivo em formato não aceito, acima de 10MB ou corrompido (a imagem não abre). No
document_extraction, também PDF com mais de 1 página. 401Unauthorized- Bearer Token ausente, inválido ou expirado.
422Validation Error- Payload válido sintaticamente, mas semanticamente incorreto: falta o arquivo ou o JSON que o check exige, ou o JSON é inválido.
500Internal Server Error- Falha interna. Tente novamente; persistindo, contate o suporte.
503Service Unavailabledev- Provedor de IA temporariamente indisponível no
document_extraction. Tente novamente em instantes.
Notas de comportamento
checksé uma lista (CSV) do que você quer executar. Apenas os checks pedidos vêm preenchidos; o restante volta comonull.approvedé o AND lógico dos checks solicitados.- Os checks rodam em paralelo sobre a mesma imagem.
- Formatos de imagem aceitos: JPG, JPEG, PNG, GIF, BMP, WEBP, DNG (máx. 10MB cada).
Pronto para integrar?
Fale com nosso time para receber credenciais de sandbox e iniciar sua integração com o Riv.IA EYE.