Inyo

Verificación Server-to-Server

Cuando ya tiene una interfaz de captura — o está verificando imágenes recogidas antes — envíelas directamente. Sin sesión, sin widget, sin enlace para el cliente.

La llamada acepta la verificación y responde con su identificador. La evaluación se ejecuta detrás de la respuesta.


Crear una Verificación

Endpoint: POST /v1/verifications
Autenticación: token Bearer con el scope verifications
Content-Type: multipart/form-data

curl --request POST \
  --url https://{FQDN}/v1/verifications \
  --header "Authorization: Bearer $ACCESS_TOKEN" \
  --header "Idempotency-Key: $(uuidgen)" \
  --form userRef=user-123 \
  --form [email protected] \
  --form [email protected] \
  --form [email protected]

Devuelve 201:

{
  "sessionId": "81e04c30-2620-42f1-a3e0-68aef1f84043",
  "status": "pending"
}

Ese es el cuerpo completo. No hay resultado en él — la extracción del documento, la revisión de autenticidad, el cribado de sanciones y las verificaciones faciales se ejecutan todas después de que usted recibe la respuesta. Guarde el sessionId: es con él que lee el resultado y reconoce el webhook cuando llega.


Obtener el Resultado

Dos canales, y puede usar ambos.

CanalCómo
WebhookCon un webhookUrl configurado para su cuenta, el resultado se envía por POST cuando la verificación alcanza un estado terminal — vea Recepción de Resultados
LecturaGET /v1/verifications/{verificationId} devuelve el estado actual, para confirmar o recuperar un desenlace

Una verificación se acepta tenga o no un destino registrado — se ejecuta, concluye y su desenlace queda recuperable en cualquier caso. El destino de webhook se acuerda con su contacto de Inyo, no se configura por la API, así que este endpoint no puede informar si existe uno. Registre uno: un bucle de consulta ajustado no es el uso previsto de la lectura.


Consultar una Verificación

Endpoint: GET /v1/verifications/{verificationId}
Autenticación: token Bearer con el scope verifications

curl --request GET \
  --url https://{FQDN}/v1/verifications/$VERIFICATION_ID \
  --header "Authorization: Bearer $ACCESS_TOKEN"
{
  "sessionId": "81e04c30-2620-42f1-a3e0-68aef1f84043",
  "userRef": "user-123",
  "status": "completed",
  "step": "done",
  "result": { "…": "el resultado normalizado, actualizado en el lugar" },
  "createdAt": "2026-09-14T14:02:11.481Z",
  "updatedAt": "2026-09-14T14:02:58.902Z"
}
CampoDescripción
statuspending, completed, failed o errored — la posición en el ciclo de vida, nunca un veredicto. El resultado, cuando lo hay, es result.decision
resultEl resultado normalizado completo una vez que termina la evaluación, null antes de eso. Actualizado en el lugar cuando un analista decide

Esta ruta sirve solo sus verificaciones. El identificador de una sesión de widget devuelve 404 aquí, y el identificador de una verificación devuelve 404 en GET /v1/sessions/{sessionId} — cada puerta lee en su propia ruta, con el scope que esa puerta emite.

El registro de una verificación no lleva deliveryMode. En una sesión de widget ese campo distingue un push de una redirección en el navegador; una verificación no tiene ninguno de los dos, e informar webhook en ella se leería como la promesa de que existe un destino, algo que usted sabe por su propia configuración y que no nos corresponde afirmar.


Idempotency-Key es obligatorio

Toda llamada debe llevar la cabecera Idempotency-Key. Una petición sin ella se rechaza con 422.

Una evaluación es trabajo real — la extracción, la revisión de autenticidad, el cribado y las verificaciones faciales se ejecutan todas contra proveedores externos. Si una respuesta se pierde en tránsito y usted reintenta a ciegas, la clave es lo que impide que cada una de ellas se ejecute una segunda vez y le deje dos registros de verificación para una persona.

Use un valor que su propio código pueda reproducir para la misma verificación lógica: un UUID que genere y almacene, o un identificador de su sistema. No lo derive de algo que se repite, como el userRef solo — dos verificaciones legítimas de la misma persona colisionarían, y la segunda devolvería el identificador de la primera.

SituaciónRespuesta
Primera llamada con una clave201 con un sessionId nuevo
Misma clave, misma petición201 con el mismo sessionId, en cualquier estado en que esté el trabajo. Nada se inicia dos veces
Misma clave, imágenes o persona distintas422 IDEMPOTENCY_KEY_REUSED. Repetirla devolvería la verificación de otra persona, así que el rechazo es deliberado

Una repetición ya no distingue trabajo en curso de trabajo terminado, porque no le hace falta: la primera respuesta ya le dio el identificador, así que un reintento no tiene nada más que decirle. Lea el status si quiere saber dónde llegó.

POST /v1/sessions no acepta Idempotency-Key. Su respuesta contiene un enlace de widget de un solo uso que no puede reemitirse, así que un reintento allí crea una sesión nueva; un duplicado cuesta un enlace sin usar, no una verificación repetida.

Cuándo una clave nueva es lo correcto

Reintentar con la misma clave es lo que quiere ante una respuesta perdida o fallida — es gratis y devuelve el identificador que no recibió.

Genere una clave nueva en un caso: la verificación terminó en errored. Eso es un fallo de plataforma de nuestro lado, no una decisión sobre su cliente. La clave antigua queda gastada en ella de forma permanente y seguirá devolviendo ese desenlace, así que una clave nueva es la que ejecuta una verificación nueva de la misma persona.

Fuera de eso, una clave nueva inicia una segunda verificación de alguien a quien ya verificó.


Campos del Formulario

CampoTipoObligatorioDescripción
userReftextoSu identificador para la persona verificada
frontImagearchivoAnverso del documento — la página de foto de un pasaporte, el frente de una tarjeta
backImagearchivoNoReverso del documento. En licencias e IDs estatales de EE. UU. es donde está el código de barras
selfieImagearchivoNoOmítalo para ejecutar solo las verificaciones documentales — vea Verificación solo de documento
dataChecktextoNotrue compara los datos extraídos con el prefill
prefilltextoNoUna cadena JSON con el mismo esquema que el prefill de sesión

Tenga en cuenta que aquí prefill es una cadena JSON dentro de un campo multipart, no un objeto anidado:

  --form 'prefill={"firstName":"Ana","lastName":"Silva","dateOfBirth":"1988-03-04"}' \
  --form dataCheck=true

Todos los campos se leen antes de responderle, así que un prefill malformado sigue siendo un 422 en la propia llamada, no algo que descubra después.


Envíe el Reverso de la Tarjeta

En licencias de conducir e IDs estatales de EE. UU., el reverso lleva un código de barras PDF417 con los datos del titular. Inyo lo decodifica al recibirlo y, como el código de barras se autoverifica — la simbología lleva su propia corrección de errores —, tiene prioridad sobre el OCR de la zona visual para los campos que contiene. La decodificación es independiente de la rotación, así que un reverso boca abajo se lee igual.

Los valores del OCR se mantienen cuando el reverso no decodifica, así que no hay desventaja en enviarlo y sí una ganancia de precisión medible cuando lo hace. Un reverso ilegible publica document_barcode_valid como not_evaluated con motivo no_barcode, lo que no cuesta nada; un reverso con un código de barras que no es un registro de identidad lo publica como failed. Los pasaportes llevan una zona legible por máquina en la página de foto, así que frontImage por sí solo basta para ellos.


Verificación Solo de Documento

Omita selfieImage para verificar el documento sin biometría. Las verificaciones documentales se ejecutan — legibilidad, formato, vigencia, autenticidad, jurisdicción — y ninguna verificación facial aparece en checks[].

Una consecuencia a prever: una verificación solo de documento no lleva ninguna evidencia biométrica y se decide únicamente por sus verificaciones documentales. Si su modelo de riesgo necesita el rostro comparado con el documento, envíe una selfie.


in_review No Es una Respuesta Final

Bajo decisionamiento gestionado, decision puede ser in_review, lo que significa que un analista aún debe decidir. status es completed en cualquier caso — es la posición en el ciclo de vida, no un veredicto.

Qué bandas de puntuación se envían a revisión se define para su cuenta, así que maneje inconclusive e in_review también en este punto de entrada.

El desenlace de la propia evaluación y la decisión posterior del analista le llegan del mismo modo: un webhook si tiene un destino, y la lectura en cualquier caso. Ya no hay una primera respuesta que llegue de forma distinta a las siguientes. Vea Revisión Manual para el cuadro completo.


Cuando la Plataforma Falla

Una verificación cuya evaluación no puede ejecutarse termina en errored. Lleva las verificaciones que concluyeron antes del fallo, no publica decision y no llega a ningún revisor — no hay nada sobre lo que actuar.

errored es distinto de failed, y la diferencia es quién reintenta:

StatusSignificadoQué hacer
failedLa captura nunca fue utilizable — en el widget, el cliente agotó los intentosLa persona vuelve a intentarlo
erroredUn fallo de nuestro lado detuvo la evaluaciónUsted repite la llamada, con una Idempotency-Key nueva

Nunca hace falta leer las filas de checks para distinguirlos.


Respuestas de Error

StatusCausaCómo manejarlo
401 / 403Token ausente o inválido, o un token sin el scope verificationsVea Autenticación
404Ninguna verificación suya lleva ese id — incluido el id de una sesión de widgetLea una sesión de widget en GET /v1/sessions/{sessionId}
422prefill no es JSON válido o viola el esquema de prefill (incluido el formato del número de documento)Corrija el payload — errors[] nombra cada campo y por qué se rechazó
422dataCheck=true sin prefillProporcione un payload de prefill con el que comparar
422errorCode: "IDEMPOTENCY_KEY_REUSED" — la clave ya se usó para una petición distintaUse una clave nueva
502No pudimos aceptar la verificaciónTransitorio — reintente con la misma clave. No se decidió nada sobre su cliente
503Demasiadas verificaciones ya en cursoTransitorio — reintente con la misma Idempotency-Key. No se inició nada, así que la clave sigue libre y el reintento no es una segunda verificación. Espere antes los segundos que indica la cabecera Retry-After

Una evaluación que falla después de haberle respondido no produce una respuesta de error — usted ya tiene un 201. Termina la verificación en errored, lo que ve en la lectura o en el webhook.


¿Widget o Server-to-Server?

Ambos puntos de entrada comparten el mismo pipeline y el mismo formato de resultado, y sus umbrales, enrutamiento de revisión, jurisdicciones aceptadas y opciones de enriquecimiento se aplican igual. Los tipos de documento permitidos son por naturaleza de nivel de sesión y no tienen efecto aquí — restringen lo que el widget ofrece al cliente. prefill.documentType sí tiene efecto: es el tipo con el que document_type_match juzga las imágenes, así que declarar uno y enviar otro documento reprueba esa verificación. Omítalo y la verificación publica not_evaluated, y el tipo de documento pasa a ser lo que indiquen las imágenes, sin nada que lo compare.

Las diferencias que importan:

Widget alojadoServer-to-server
Calidad de la capturaGuiada, con encuadre en vivo y aviso de reflejosBajo su control
Captura fallidaEl cliente recibe indicaciones y reintentaTermina en failed; reintentar es decisión suya
Entrega del resultadoWebhook o redirección firmadaWebhook cuando está configurado, y la lectura en cualquier caso
Lectura del registroGET /v1/sessions/{sessionId}GET /v1/verifications/{verificationId}
Defensa ante ataques de presentaciónLas mismas verificacionesLas mismas verificaciones, pero sin contexto de captura en vivo en el que apoyarse
Evidencia de cumplimientoInyo conserva la captura guiada y el video de selfie opcionalSolo las imágenes que usted envíe

La diferencia de reintento tiene que ver con guiar a un cliente en vivo — no cambia lo que significa su configuración ni cómo se alcanza la decisión.


Próximos Pasos