Referencia de la API
La referencia de la API de verificación de identidad.
Cada endpoint que puede llamar, cada campo que recibirá de vuelta y qué hacer con un webhook cuando llegue. Para conocer los tipos de campo exactos, considere el documento OpenAPI en vivo, en /docs, en el origen de su propia API, como la fuente de verdad; esta página es la versión en lenguaje sencillo.
URL base y entornos
Una URL base. Dos entornos.
Todas las solicitudes van al mismo host. El entorno en el que se encuentra lo determina por completo la clave de API que envíe.
| URL base (esta documentación) | https://api.shieldid.ca — illustrative; your production API origin is published together with your API keys. |
|---|---|
| Encabezado de autenticación | X-Api-Key: <su clave>, en cada solicitud excepto los dos endpoints públicos indicados a continuación. |
| Prefijo de clave del entorno de pruebas (sandbox) | vk_sand_… — las sesiones creadas con esta clave se marcan con environment: "sandbox" y nunca se facturan. |
| Prefijo de clave de producción | vk_live_… — las mismas solicitudes, facturadas según su plan. |
| Tipo de contenido | application/json en el cuerpo de cada solicitud y respuesta. |
Endpoints
Toda la superficie de v1.
Seis endpoints JSON, más una página alojada y una verificación pública de credenciales que no son JSON en absoluto: solo se enlazan.
| Endpoint | Auth | What it does |
|---|---|---|
| POST /v1/sessions | X-Api-Key | Cree una sesión de verificación. Requiere return_url y webhook_url. Devuelve session_id, verification_url y status: "PENDING". |
| GET /v1/sessions/{id} | X-Api-Key | Estado y campos principales de una sesión: status, confidence, environment. |
| GET /v1/sessions/{id}/result | X-Api-Key | El resultado completo una vez que una sesión alcanza VERIFIED o FAILED: person, veredictos por verificación, confidence, verified_until. |
| DELETE /v1/sessions/{id} | X-Api-Key | Cancele una sesión que todavía esté PENDING o IN_PROGRESS. Una sesión que ya esté en VERIFIED, FAILED o EXPIRED no se puede cancelar. |
| GET /v1/credentials/{token} | None — public | Compruebe si una credencial verificada es válida actualmente. No requiere clave de API, por lo que se puede invocar desde un navegador. Nota: la respuesta actual también incluye el nombre de la persona verificada y el tipo y país del documento, no solo un indicador de válido/no válido; no entregue este enlace a un tercero que no desee que vea esa información. |
| GET /v1/pricing/{country} | X-Api-Key | Precios por país para un código de país ISO 3166-1 de dos letras. |
| /v/{session_id} | La página de verificación alojada: la verification_url que devuelve una sesión. En el escritorio muestra un código QR; al escanearlo, el teléfono del solicitante recibe el mismo enlace para capturar su documento y su selfie. |
|---|---|
| /c/{session_id} | Una página pública de comprobación de credenciales, sin autenticación, para una sesión verificada. Nota: la respuesta actual también incluye el nombre de la persona verificada y el tipo y país del documento, no solo un indicador de válido/no válido; no entregue este enlace a un tercero que no desee que vea esa información. |
| /docs | La referencia OpenAPI interactiva y en vivo para el origen de API de su cuenta. |
Crear una sesión
POST /v1/sessions, de principio a fin.
La solicitud y exactamente lo que se devuelve.
curl -X POST https://api.shieldid.ca/v1/sessions \
-H "X-Api-Key: vk_sand_your_key" \
-H "Content-Type: application/json" \
-d '{
"return_url": "https://yourapp.example/verified",
"webhook_url": "https://yourapp.example/hooks/shieldid",
"expected_name": "Jordan Smith",
"locale": "en",
"metadata": { "application_id": "app_9182" }
}'| return_url | string, obligatorio — Adónde se redirige al solicitante cuando termina. Debe ser http o https. |
|---|---|
| webhook_url | string, obligatorio — Adónde se entrega el resultado firmado. Consulte Webhooks más abajo. |
| expected_name | string, obligatorio — El nombre que espera en el documento, utilizado para contrastar lo que realmente dice la identificación. |
| expected_dob / expected_address | string, opcional — Se contrasta con el documento cuando se proporciona; no es obligatorio para ejecutar una verificación. |
| locale | string, opcional — "en" o "fr". Define el idioma de la página alojada que ve el solicitante. |
| metadata | object, opcional — Sus propios datos de referencia: un id de solicitud, un id de inquilino, lo que desee que se devuelva sin cambios en el resultado y en el webhook. |
El resultado
GET /v1/sessions/{id}/result — estructura de la respuesta.
La misma estructura se entrega en la carga del webhook, por lo que rara vez necesita consultar este endpoint.
| session_id | El id que creó. |
|---|---|
| status | PENDING, IN_PROGRESS, VERIFIED, FAILED o EXPIRED. |
| environment | "sandbox" o "production", según la clave que creó la sesión. |
| person | Los campos leídos del documento: nombre, fecha de nacimiento, tipo de documento, país y jurisdicción del documento, dirección. |
| checks | Un veredicto por cada verificación; consulte más abajo. Nunca un único puntaje opaco. |
| confidence | Una cifra global única para la verificación. Las verificaciones individuales, incluida la comparación facial, se siguen informando por separado frente a un umbral de decisión fijo; este campo no las reemplaza. |
| verified_until | Durante cuánto tiempo se considera vigente el resultado, en una sesión VERIFIED. |
| failure_reason | Se establece en una sesión FAILED, por ejemplo FACE_MATCH_BELOW_THRESHOLD o CANCELLED_BY_API. De lo contrario, es null. |
| metadata | Lo que haya enviado al crear la sesión, sin cambios. |
{
"session_id": "ses_9f2c1a",
"status": "VERIFIED",
"environment": "sandbox",
"person": {
"name": "Jordan Smith",
"dob": "1994-03-11",
"document_type": "drivers_licence",
"document_country": "CA",
"document_jurisdiction": "ON"
},
"checks": {
"document": "PASS",
"liveness": "PASS",
"antispoof": "PASS",
"face_match": "PASS"
},
"confidence": 88,
"verified_until": "2027-03-11T00:00:00Z",
"failure_reason": null,
"metadata": { "application_id": "app_9182" }
}Add-onchecks.document, checks.liveness, checks.antispoof y checks.face_match se resuelven cada uno como PASS, FAIL o SKIPPED. La verificación contra listas de vigilancia (checks.sanctions: CLEAR, MATCH o SKIPPED) es un complemento y solo aparece en las cuentas que lo activan.
Ciclo de vida de la sesión
Cinco estados, un solo camino.
Una sesión avanza por sí sola; usted no controla la máquina de estados, solo la consulta.
| PENDING | Creada. Nadie ha abierto aún la verification_url. |
|---|---|
| IN_PROGRESS | El solicitante abrió el enlace y se encuentra en algún punto del flujo de captura. |
| VERIFIED | Se ejecutaron todas las verificaciones y el resultado está listo. Estado final: consulte el endpoint de resultados o lea el webhook. |
| FAILED | Al menos una verificación no se aprobó. failure_reason indica cuál. Próximamente: un reintento que restablece la sesión a PENDING; mientras tanto, trate FAILED como estado final y cree una nueva sesión si el solicitante desea intentarlo de nuevo. |
| EXPIRED | Nadie terminó a tiempo. Las sesiones vencen automáticamente después de un plazo predeterminado (30 minutos); cree una nueva para intentarlo de nuevo. |
DELETE /v1/sessions/{id} cancela anticipadamente una sesión PENDING o IN_PROGRESS. Una sesión que ya alcanzó VERIFIED, FAILED o EXPIRED no se puede cancelar: ya terminó.
Errores
Lo que debe prever.
Esta es la lista corta que vale la pena codificar hoy. El conjunto completo y actualizado de códigos de error y cargas útiles está documentado en el OpenAPI en vivo, en /docs.
| Status | Code | Meaning |
|---|---|---|
| 401 | UNAUTHORIZED | Falta el encabezado X-Api-Key. |
| 401 | INVALID_KEY_FORMAT | La clave no comienza con vk_sand_ ni con vk_live_, o no coincide con ninguna clave de la cuenta. |
| 403 | FORBIDDEN | La clave es válida, pero no tiene acceso a la sesión o al recurso solicitado. |
| 404 | NOT_FOUND | No existe ninguna sesión, credencial o recurso con ese id. |
| 409 | CONFLICT | La sesión no está en un estado que permita la acción, por ejemplo, al intentar cancelar una que ya está VERIFIED. |
| 422 | VALIDATION_ERROR | Falta un campo obligatorio o tiene un formato incorrecto; por ejemplo, return_url no es una URL http o https válida. |
Webhooks
Firmado, entregado, reintentado.
Cuando una sesión llega a VERIFIED o FAILED, ShieldID envía mediante POST la estructura documentada arriba a su webhook_url.
- Se entrega como una solicitud POST con un cuerpo JSON que coincide con la estructura del resultado indicada arriba.
- Firmado con HMAC-SHA256 sobre el cuerpo sin procesar de la solicitud y enviado en un encabezado X-Bio-Signature. Verifíquelo con el secreto de su webhook antes de confiar en la carga útil.
- Se reintenta hasta tres veces con un retroceso lineal si su endpoint no responde con un estado 2xx.
- Próximamente: un reintento de sesiones FAILED que entregará un segundo webhook cuando se resuelva. Por ahora, considere como regla un webhook por sesión.
- Los nombres de los campos aquí coinciden con esta referencia. Si lo que llega realmente es distinto, confíe en la carga útil en vivo por encima de esta página e infórmenos; la lista de campos se mantiene al día con la API, y no al revés.
Verifique la firma
import crypto from "node:crypto";
function isValidShieldIdSignature(rawBody, signatureHeader, secret) {
const expected = crypto.createHmac("sha256", secret).update(rawBody).digest("hex");
const provided = signatureHeader || "";
const a = Buffer.from(expected, "hex");
const b = Buffer.from(provided, "hex");
return a.length === b.length && crypto.timingSafeEqual(a, b);
}
// rawBody must be the exact, unparsed request body
app.post("/hooks/shieldid", express.raw({ type: "application/json" }), (req, res) => {
const ok = isValidShieldIdSignature(req.body, req.headers["x-bio-signature"], process.env.SHIELDID_WEBHOOK_SECRET);
if (!ok) return res.status(401).send("invalid signature");
const result = JSON.parse(req.body);
// result.session_id, result.status, result.checks, …
res.status(200).send("ok");
});Idempotencia y reintentos
Cree controladores que se puedan ejecutar dos veces sin riesgo.
Todavía no existe una clave de idempotencia dedicada, ni al crear la sesión ni en la entrega del webhook.
- Una entrega de webhook reintentada puede llegar más de una vez para la misma sesión. Identifique su controlador con session_id + status y haga que el registro del resultado sea idempotente.
- No reintente POST /v1/sessions a ciegas tras un tiempo de espera agotado; primero verifique si la sesión se creó, o podría terminar con dos sesiones para un mismo solicitante.
- Se tiene previsto un encabezado Idempotency-Key dedicado para la creación de sesiones.
PróximamenteCompatibilidad con Idempotency-Key en la creación de sesiones
Cómo mantenerse al día
Esta referencia cambia. Siga el registro de cambios.
Las incorporaciones de campos, los nuevos códigos de error y los cambios de endpoints se anuncian allí antes de llegar aquí.
Preguntas
Preguntas frecuentes de la referencia.
Siguiente
Ponga en práctica esta referencia.
Siga la guía de inicio rápido para pasar, en orden, de una clave del entorno de pruebas (sandbox) a una sesión verificada y un webhook firmado.