Riv.IA EYE API
Verificación visual de identidad por API REST. Un único endpoint ejecuta cualquier combinación de checks sobre la misma imagen, autenticado con Bearer Token.
- Producción
- https://api.riv.ia.br
- Dev
- https://dev.riv.ia.br
Cómo usar la API
Todos los endpoints exigen un Bearer Token. Genera el token primero e inclúyelo en el header de cada petición.
- 1
Generar token
Autentícate con client_id y client_secret para recibir el Bearer Token.
- 2
Enviar imagen
Haz POST en /eye/v1/verify con la imagen y los checks deseados.
- 3
Recibir veredicto
Respuesta JSON explicable con el veredicto agregado approved.
¿Necesitas credenciales? Para obtener tu client_id y client_secret, escríbenos al email contato@riviadev.com.br.
Autenticación
Usa tus credenciales para generar un Bearer Token de corta duración. Inclúyelo en el header Authorization: Bearer <token> en todas las llamadas siguientes.
/auth/v1/tokens/generateCambia tus credenciales por un Bearer Token de acceso.
Body (application/json)
client_idstringobligatorio- Identificador del cliente proporcionado por RiviaDev.
client_secretstringobligatorio- Secreto del cliente. Guárdalo bien — nunca lo expongas en código del lado del cliente.
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
Punto de entrada único para la verificación visual. Combina los checks que necesites en checks — el veredicto approved es la conjunción de todos los checks solicitados.
/eye/v1/verifylivenessPrueba de vidaselfieface_matchComparación facialselfie+documentauthenticityAutenticidad / antisuplantaciónselfieelement_detectionDetección de elementosselfie+detection_requesttext_extractionExtracción de textoselfie+extraction_requestqr_codeLectura de código QRselfie(+extraction_requestopcional)document_extractiondevExtracción de documentodocument(sinselfie)
Headers
Authorizationstringobligatorio- Bearer Token obtenido en
/auth/v1/tokens/generate. Formato:Bearer <token>.
Body (multipart/form-data)
checksstringobligatorio- Lista de checks a ejecutar, separados por comas:
liveness,face_match,authenticity,element_detection,text_extraction,qr_code,document_extraction. selfiefile- Imagen a verificar: el selfie de la persona o, en
qr_code, la foto con el código QR. Formatos: JPG, JPEG, PNG, GIF, BMP, WEBP, DNG (máx. 10MB). Obligatorio con todos los checks, salvo cuando solo se pidedocument_extraction. documentfile- Imagen del documento. Obligatorio con
face_matchydocument_extraction. Endocument_extractionacepta también PDF de 1 página. detection_requeststring (JSON)- JSON con los elementos a detectar. Obligatorio con
element_detection. extraction_requeststring (JSON)- JSON con los campos de texto a leer. Obligatorio con
text_extraction; opcional conqr_code, donde habilita el fallback a OCR.
Respuesta
Cada check solicitado vuelve como un objeto con su propio nombre; los no solicitados vuelven como null. El esquema de cada objeto está en la sección del check.
successboolean- Indica si la llamada se procesó correctamente.
approvedboolean- Veredicto agregado: true cuando todos los checks solicitados pasaron.
checksstring[]- Lista de los checks realmente ejecutados, en orden.
<check>object | null- Resultado de cada check solicitado.
nullpara los no solicitados. messagestring | null- Mensaje complementario legible sobre el resultado.
Los textos legibles de la respuesta (message, details, reasons, resúmenes) se devuelven en portugués, como en los ejemplos.
Varios checks en una llamada
Combina los checks en la misma petición — se ejecutan en 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
livenessPrueba de vida
Verifica si la imagen es un selfie real de una persona viva — no una foto de pantalla, impresa o generada por IA.
Enviar: checks=liveness + selfie
Objeto liveness
resultadoboolean- true cuando la imagen es un selfie real de un ser humano. Es lo que entra en
approved. person_presentboolean | null- Si hay una persona física en la imagen.
confidencefloat | null- Confianza del veredicto.
detalhesstring[]- Motivos del rechazo. Vacío cuando se aprueba.
authenticityobject | null- Veredicto antisuplantación calculado en la misma inferencia. Mismo esquema que el check
authenticity.
Comportamiento
- Pedir
livenessjunto conauthenticityconsume una única inferencia: el resultado antisuplantación se reutiliza.
Selfie real de una persona 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_matchComparación facial
Compara el rostro del selfie con la foto del documento e indica si son la misma persona.
Enviar: checks=face_match + selfie + document
Objeto face_match
same_personboolean- true cuando el selfie y el documento son de la misma persona.
confidencefloat- Confianza de la comparación, de 0 a 1.
detailsstring[]- Detalles estructurales del análisis (ojos, nariz, contorno).
Comportamiento
- Sin
documentla API responde422.
Selfie y documento de la misma persona.
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"
}authenticityAutenticidad / antisuplantación
Detecta foto de pantalla, foto impresa o imagen generada por IA. Funciona con cualquier imagen, con persona u objeto.
Enviar: checks=authenticity + selfie
Objeto authenticity
is_authenticboolean- true cuando la imagen no es una suplantación.
is_screen_photoboolean- Foto de pantalla o monitor.
is_printed_photoboolean- Foto de material impreso.
is_ai_generatedboolean- Imagen generada por IA.
confidencefloat- Confianza del veredicto.
signalsstring[]- Señales estructurales observadas (ej.: moiré, rejilla de píxeles, borde del monitor).
reasonsstring[]- Justificación legible del veredicto.
Comportamiento
- Los reflejos y brillos por sí solos nunca clasifican la imagen como foto de pantalla: hacen falta al menos 2 artefactos estructurales.
Sin evidencia de suplantación.
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_detectionDetección de elementos
Verifica si los elementos esperados están en la imagen: ropa, accesorios, objetos, textos, logos, colores o personas.
Enviar: checks=element_detection + selfie + detection_request
detection_requeststring (JSON)obligatorio- Hasta 5 elementos.
type:clothing,accessory,object,text,logo,color_schemeoperson.expected_count(1–10) es opcional, útil para personas. Ej.:{"elements":[{"type":"object","description":"crachá","required":true}]}.
Objeto element_detection
all_required_foundboolean- true cuando se encontraron todos los elementos obligatorios.
detection_summarystring- Resumen legible del análisis.
detected_elementsobject[]- Resultado de cada elemento solicitado. Esquema abajo.
blocked_by_authenticityboolean- true cuando la lista vino vacía porque la imagen no superó el filtro antisuplantación, y no por un fallo en la detección.
Cada ítem de detected_elements
typestring- Tipo del elemento solicitado.
descriptionstring- Descripción del elemento solicitado.
foundboolean- Si se encontró el elemento.
confidencefloat- Confianza de la detección.
detailsstring- Detalles sobre la detección o la ausencia.
quantity_foundinteger | null- Cantidad encontrada, cuando se envió
expected_count.
Comportamiento
- Sin
detection_requestla API responde422. - La detección pasa por el filtro antisuplantación aunque no se pida
authenticity.
Credencial obligatoria encontrada.
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_extractionExtracción de texto
Lee campos de texto concretos de la imagen, como un código impreso en una etiqueta, con validación de formato opcional.
Enviar: checks=text_extraction + selfie + extraction_request
extraction_requeststring (JSON)obligatorio- Hasta 5 campos.
expected_formates una regex RE2 opcional (full match; sin backreference ni lookaround). Ej.:{"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 cuando se leyeron y validaron todos los campos obligatorios.
extraction_summarystring- Resumen legible de la extracción.
extracted_fieldsobject[]- Resultado de cada campo solicitado. Esquema abajo.
blocked_by_authenticityboolean- true cuando la lista vino vacía porque la imagen no superó el filtro antisuplantación, y no por un fallo en la lectura.
Cada ítem de extracted_fields
namestring- Nombre del campo solicitado.
valuestring | null- Texto leído.
nullcuando no se leyó. foundboolean- Si el valor se leyó y, si hay formato, se validó.
confidencefloat- Confianza de la lectura.
matches_formatboolean | null- Si el valor coincidió con el
expected_format.nullcuando no hay formato. detailsstring- Detalles sobre la lectura o la ausencia.
Comportamiento
- Sin
extraction_request, o con JSON inválido, la API responde422. - La lectura pasa por el filtro antisuplantación aunque no se pida
authenticity.
Campo leído y validado por el 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_codeLectura de código QR
Lee el código QR de la foto. Con extraction_request, lee el código impreso cuando el QR falta, está ilegible o vacío.
Enviar: checks=qr_code + selfie (+ extraction_request opcional)
Objeto qr_code
foundboolean- true cuando se leyó un valor y, si hay
expected_format, coincidió con él. valuestring | null- Texto leído del QR o por OCR.
nullcuando no hay una lectura válida. source"qr" | "ocr" | null- Origen del valor.
status"read" | "ocr_fallback" | "not_found"read: leído del QR.ocr_fallback: leído por OCR porque no había un QR legible.not_found: no se leyó nada válido.confidencefloat | null- Confianza de la lectura.
1.0en el camino QR — el decode se valida con Reed-Solomon, así que o sale el valor grabado o no sale nada. En el fallback, la confianza del campo leído por el OCR.nullcuando no se leyó nada. matches_formatboolean | null- Si el valor coincidió con el
expected_format.nullcuando no hay formato. Un QR leído que no coincide con el formato devuelvenot_foundconmatches_format=false, sin activar el OCR. qr_countinteger- Cantidad de códigos QR con texto detectados en la foto. Con más de uno, gana el de mayor área.
detailsstring- Motivo legible de la lectura (ej.: QR sin texto, timeout en la decodificación, DNG leído directamente por OCR). Texto libre: no lo uses en lógica.
blocked_by_authenticityboolean- true cuando la imagen no superó el filtro antisuplantación (foto de pantalla, impresa o generada por IA). En ese caso
found=false,value=nullystatus=not_found.
Comportamiento
approvedexige código leído e imagen auténtica — la lectura pasa por el filtro antisuplantación aunque no se pidaauthenticity.- No leer nada es
200conapproved=falseystatus=not_found, no400. - Los archivos DNG van directo al OCR, así que solo se leen con
extraction_request.
Con varios QR, gana el de mayor área. Sin extraction_request no hay 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_extractiondevExtracción de documento
Identifica si la imagen es un documento y, si es un RG o una CNH brasileños, devuelve los campos extraídos con confianza por campo.
Enviar: checks=document_extraction + document (sin selfie)
documentfileobligatorio- Imagen JPEG, PNG o WebP, o PDF de 1 página (ej.: CNH digital exportada de la app Carteira Digital de Trânsito), hasta 10MB. Una cara por llamada — anverso o reverso; la CNH digital trae las dos en la misma página.
Objeto document_extraction
type"rg" | "cnh" | "not_a_document" | "unsupported_document" | "unreadable_document"rgycnhaprueban.not_a_document,unsupported_document(ej.: pasaporte, CRLV, diploma) yunreadable_documentrechazan:approved=false,fields=nullymessageexplica el motivo.model"legacy" | "cin" | "physical" | "digital" | null- Modelo del documento:
legacyocinpara RG,physicalodigitalpara CNH.nullcuando no se determina. side"front" | "back" | "both" | null- Cara enviada:
front,backoboth.nullcuando no se determina. classification_confidencefloat- Confianza de la clasificación del tipo de documento.
fieldsobject | null- Campos extraídos, cada uno como
{value, confidence}. Todas las claves del tipo vienen siempre; un campo ilegible viene como{value: null, confidence: 0}— nunca un valor inventado, así que tú decides qué va a revisión humana.nullen los tipos de rechazo. messagestring | null- Motivo del rechazo.
nullcuando el documento es RG o 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- Fechas en
YYYY-MM-DD. CPF en formato000.000.000-00, validado por el dígito verificador. Nombres sin tildes y en mayúsculas. Filiación en el orden impreso, sin distinguir padre y madre.
Comportamiento
- Un rechazo también es
200, conapproved=false. - Combinable:
liveness,face_match,document_extractionhace el KYC completo en una llamada — entoncesselfievuelve a ser obligatorio. - No hay retención: la imagen y los campos extraídos no se almacenan ni se registran en logs.
- Sin
documentla API responde422; un PDF de más de 1 página responde400.
Reverso de un RG. Un campo ilegible viene con value null y confidence 0.Disponible solo en el entorno dev mientras está en validación; aún no está en producción.
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 estado
200OK- Verificación procesada. Un rechazo de negocio también es 200 con
approved=false. 400Bad Request- Parámetros inválidos, archivo en un formato no aceptado, de más de 10MB o dañado (la imagen no se puede abrir). En
document_extraction, también PDF de más de 1 página. 401Unauthorized- Bearer Token ausente, inválido o caducado.
422Validation Error- Payload válido sintácticamente pero semánticamente incorrecto: falta el archivo o el JSON que exige el check, o el JSON es inválido.
500Internal Server Error- Fallo interno. Inténtalo de nuevo; si persiste, contacta con soporte.
503Service Unavailabledev- Proveedor de IA temporalmente no disponible en
document_extraction. Inténtalo de nuevo en unos instantes.
Notas de comportamiento
checkses una lista (CSV) de lo que quieres ejecutar. Solo los checks pedidos vuelven rellenos; el resto vuelve comonull.approvedes el AND lógico de los checks solicitados.- Los checks se ejecutan en paralelo sobre la misma imagen.
- Formatos de imagen aceptados: JPG, JPEG, PNG, GIF, BMP, WEBP, DNG (máx. 10MB cada uno).
¿Listo para integrar?
Habla con nuestro equipo para recibir credenciales de sandbox y empezar tu integración con Riv.IA EYE.