Referencia de la API

Sesiones de verificación

Crear, listar, consultar y cancelar sesiones. Shapes completos.

Una sesión de verificación es una corrida del flujo de un proyecto para una persona. Se crea desde tu backend, la completa la persona en su celular y termina en un estado terminal con un veredicto.

El objeto sesión

CampoTipoRequeridoDescripción
idstringsiempreId de la sesión, vs_….
objectstringsiempreConstante "verification_session".
statusenumsiempreEstado del ciclo de vida. Ver la tabla de abajo.
modeenumsiempre"live" o "test", según la clave con la que se creó.
project_idstringsiempreProyecto al que pertenece, prj_….
config_versionstringsiempreVersión del flujo congelada al crear la sesión, cfg_00000003.
created_atstringsiempreISO 8601 UTC.
urlstringsólo al crearLink del flujo para la persona. Irrecuperable después de la respuesta de creación.
qrobjectsólo al crearObjeto con svg y png: URLs públicas del QR de ese link.
expires_atstringsólo al crearCuándo vence el link.
external_refstringsi se envióEco de tu referencia externa. Viaja también en los webhooks.
metadataobjectsi se envióEco de la metadata enviada al crear. Ver la nota de abajo.
resultobjectsi hay resoluciónVeredicto de la sesión. Aparece cuando el estado ya no es pending ni in_progress.
completed_atstringsi es terminalCuándo quedó en estado terminal.

Estados

CampoTipoTerminalDescripción
pendingCreadanoEl link existe pero todavía nadie lo abrió.
in_progressEn cursonoLa persona está completando el flujo.
needs_reviewEn revisiónnoEl flujo terminó pero la decisión quedó para revisión humana.
approvedAprobadaVerificación exitosa.
rejectedRechazadaVerificación fallida. Los motivos están en result.reason_codes.
expiredVencidaEl link venció sin que la persona terminara.
abandonedAbandonadaLa persona empezó y dejó el flujo inactivo más allá del tiempo permitido.
canceledCanceladaCancelada por vos con el endpoint de cancelación.

Los estados terminales son inmutables: una sesión aprobada no vuelve a cambiar.

El objeto result

CampoTipoRequeridoDescripción
outcomeenumsiempreapproved, rejected, review_required, expired, abandoned o canceled. Es la traducción pública de status: needs_review se publica como review_required.
reason_codesstring[]siempreMotivos del veredicto, ordenados de más a menos severo. Array vacío en una aprobación limpia. Ver Reason codes.
stepsobject[]siempreUn item por paso ejecutado: { id, type, verdict }. verdict es approved, rejected, review o retryable.

Crear una sesión

POST/v1/verification-sessionsAPI key · sessions:write

Cuerpo

CampoTipoRequeridoDescripción
project_idstringProyecto a usar, prj_…. Tiene que tener una configuración publicada en el modo de tu clave.
external_refstringnoTu identificador de correlación (id del cliente, número de trámite). De 1 a 255 caracteres. Vuelve en la respuesta y en los webhooks.
expires_in_hoursnumbernoVigencia del link, entre 0.25 (15 minutos) y 168 (7 días). Si no lo mandás rige el valor del proyecto (por defecto 24 h).
prefillobjectno{ email?, phone? }. El teléfono va en E.164 (+5491122334455). Ver la advertencia de abajo.
metadataobjectnoDiccionario de strings: hasta 20 claves de 1 a 64 caracteres, con valores de hasta 500. Ver la advertencia de abajo.

El cuerpo es estricto: un campo que no esté en esta tabla devuelve 422.

Headers

CampoTipoRequeridoDescripción
AuthorizationstringBearer sk_live_… o Bearer sk_test_….
Content-Typestringapplication/json.
Idempotency-KeystringnoDe 1 a 255 caracteres. Ver Convenciones.

Ejemplo

curl -sS -X POST "$KYCAR_API/v1/verification-sessions" \
  -H "Authorization: Bearer $KYCAR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: alta-4821" \
  -d '{
    "project_id": "prj_01J9Z2K3M4N5P6Q7R8S9T0V1W2",
    "external_ref": "cliente-4821",
    "expires_in_hours": 48
  }'

201 Created:

{
  "id": "vs_01K2M4P6R8T0V2X4Z6B8D0F2H4",
  "object": "verification_session",
  "status": "pending",
  "mode": "live",
  "project_id": "prj_01J9Z2K3M4N5P6Q7R8S9T0V1W2",
  "config_version": "cfg_00000003",
  "url": "https://verify.kyc.ar/s/lt_9pQ2vLxK7sYdN1bTfR4mHc8jWgE3aZuQ5nS0oXpVtB",
  "qr": {
    "svg": "https://api.kyc.ar/v1/qr/lt_9pQ2vLxK7sYdN1bTfR4mHc8jWgE3aZuQ5nS0oXpVtB.svg",
    "png": "https://api.kyc.ar/v1/qr/lt_9pQ2vLxK7sYdN1bTfR4mHc8jWgE3aZuQ5nS0oXpVtB.png"
  },
  "expires_at": "2026-08-21T14:03:11.000Z",
  "created_at": "2026-08-19T14:03:11.482Z",
  "external_ref": "cliente-4821"
}

Errores

CampoTipoStatusDescripción
validation_failed422422Body inválido, project_id inexistente, o el proyecto no tiene configuración activa en el modo de la clave.
insufficient_tokens402402Sin saldo. No se crea nada. Trae required, balance y top_up_url como extensiones.
conflict409409Idempotency-Key reutilizada con otro payload, o con un request todavía en curso.
rate_limited429429Throttling del stage.

Listar sesiones

GET/v1/verification-sessionsAPI key · sessions:read
CampoTipoRequeridoDescripción
limitintegerno1 a 100. Por defecto 25.
cursorstringnoCursor opaco de la página anterior.
statusenumnoFiltra por uno de los ocho estados. Un valor fuera del enum devuelve 422.
curl -sS "$KYCAR_API/v1/verification-sessions?status=needs_review&limit=50" \
  -H "Authorization: Bearer $KYCAR_API_KEY"
{
  "data": [
    {
      "id": "vs_01K2M4P6R8T0V2X4Z6B8D0F2H4",
      "object": "verification_session",
      "status": "needs_review",
      "mode": "live",
      "project_id": "prj_01J9Z2K3M4N5P6Q7R8S9T0V1W2",
      "config_version": "cfg_00000003",
      "created_at": "2026-08-19T14:03:11.482Z",
      "external_ref": "cliente-4821"
    }
  ],
  "has_more": false
}

No hay filtro por project_id ni por external_ref en este endpoint. Si necesitás buscar por tu referencia externa, guardá el vs_… que te devuelve la creación junto a tu registro.


Consultar una sesión

GET/v1/verification-sessions/{id}API key · sessions:read
curl -sS "$KYCAR_API/v1/verification-sessions/vs_01K2M4P6R8T0V2X4Z6B8D0F2H4" \
  -H "Authorization: Bearer $KYCAR_API_KEY"
{
  "id": "vs_01K2M4P6R8T0V2X4Z6B8D0F2H4",
  "object": "verification_session",
  "status": "rejected",
  "mode": "live",
  "project_id": "prj_01J9Z2K3M4N5P6Q7R8S9T0V1W2",
  "config_version": "cfg_00000003",
  "created_at": "2026-08-19T14:03:11.482Z",
  "external_ref": "cliente-4821",
  "result": {
    "outcome": "rejected",
    "reason_codes": ["DOC_FIELD_MISMATCH"],
    "steps": [
      { "id": "consent", "type": "consent", "verdict": "approved" },
      { "id": "documento", "type": "document_ar", "verdict": "rejected" }
    ]
  },
  "completed_at": "2026-08-19T14:19:02.884Z"
}

Un id malformado y un id inexistente devuelven lo mismo: 404 con code: "not_found". Es deliberado — la API no sirve para descubrir qué ids existen.


Cancelar una sesión

POST/v1/verification-sessions/{id}/cancelAPI key · sessions:write

Cierra una sesión que todavía no llegó a un estado terminal: frena la ejecución del flujo, deja la sesión en canceled y emite el evento verification_session.canceled.

curl -sS -X POST "$KYCAR_API/v1/verification-sessions/vs_01K2M4P6R8T0V2X4Z6B8D0F2H4/cancel" \
  -H "Authorization: Bearer $KYCAR_API_KEY"

Devuelve 200 con el objeto sesión ya cancelado.

CampoTipoStatusDescripción
conflict409409La sesión ya estaba en un estado terminal. Cancelar dos veces devuelve este error, no un 200.
not_found404404No existe (o el id es inválido).