Para desarrolladores

Documentación de la API

Todo lo que necesita para integrar la verificación de documentos: REST + JSON, webhooks firmados, sandbox gratuito, OpenAPI y SDK.

Introducción

La API de Validento verifica identidad, documentos e ingresos dentro de su producto — para dar de alta a un cliente (KYC), contratar a alguien de otro país, aceptar a un inquilino o comprador, o firmar con un socio comercial. Envíe los documentos de una persona (o un enlace para que los suba ella) y reciba una puntuación, una decisión y las desviaciones encontradas — por webhook o consultando.

Base URLhttps://api.validento.com
FormatoJSON (UTF-8) · HTTPS · REST
Versiónv1 · cabecera Validento-Version: 2026-10-01
Entornosvld_test_… sandbox (gratis, resultados deterministas) · vld_live_… producción
DatosAnálisis en la UE (Países Bajos); resultados guardados en EE. UU. (Supabase, Oregón). Los documentos no se guardan tras el análisis.

Inicio rápido

  1. Cree una clave sandbox

    Panel Enterprise → Desarrolladores → Claves API → “+ Clave sandbox”. Se muestra una sola vez: guárdela en su gestor de secretos.

  2. Compruebe la clave
    curl https://api.validento.com/v1/me \
      -H "Authorization: Bearer vld_test_YOUR_SANDBOX_KEY"
  3. Cree una comprobación
    curl https://api.validento.com/v1/screenings \
      -H "Authorization: Bearer vld_test_YOUR_SANDBOX_KEY" \
      -H "Content-Type: application/json" \
      -H "Idempotency-Key: $(uuidgen)" \
      -d '{
        "applicant": { "name": "Ana García", "email": "ana@example.com" },
        "purpose": "client_onboarding",
        "country": "ES",
        "reference": "case-1042",
        "consent_confirmed": true,
        "case_details": { "source_of_funds": "salary", "employer": "Acme SL" },
        "documents": [
          { "type": "payslip", "url": "https://files.yourapp.com/signed/payslip-sept.pdf" },
          { "type": "bank_statement", "media_type": "application/pdf", "data": "JVBERi0xLjQK..." }
        ],
        "metadata": { "customer_id": "c_981" }
      }'
  4. Reciba el resultado

    Registre un endpoint de webhook (panel o API) y reciba screening.completed. O consulte GET /v1/screenings/{id} hasta que status deje de ser processing (normalmente 10–60 s; sandbox: al instante).

  5. Pase a live

    Cuando su integración funciona en sandbox, su gestor de cuenta activa live. Cambie la clave por una vld_live_…; el código no cambia.

Pruébelo aquí

Pegue una clave sandbox y llame a la API directamente. La clave se queda en esta pestaña (sessionStorage) y solo viaja a api.validento.com.

Autenticación y claves

Envíe la clave en cada petición como Authorization: Bearer vld_…. Solo se guarda un hash: si la pierde, cree otra. Las claves son de servidor: nunca en un navegador ni en una app móvil.

Permisos (scopes)

Una clave tiene acceso completo (*) o es restringida: déle a cada sistema solo lo que necesita. write incluye read. Sin el permiso: 403 missing_scope.

ScopePermite
screenings:readLeer comprobaciones e informes.
screenings:writeCrear y borrar comprobaciones (+ leer).
links:readLeer enlaces de verificación.
links:writeCrear y cancelar enlaces (+ leer). Ideal para el backend de su frontend.
id_checks:read / id_checks:writeLeer / crear y cancelar verificaciones de identidad (ValiD).
sanctions:read / sanctions:writeLeer / crear comprobaciones de sanciones y PEP.
webhooks:read / webhooks:writeGestionar endpoints; reenviar eventos.
events:readLeer eventos (30 días).
usage:readUso del periodo y facturas.
settings:read / settings:writeAjustes: reglas, marca, formato, avisos.

Rotación sin cortes

“Rotar” crea una clave nueva y deja la antigua viva durante el periodo de gracia que elija (0 h, 1 h, 24 h o 7 días). Despliegue la nueva, confirme en el registro de peticiones que la antigua ya no se usa y deje que caduque. ¿Clave expuesta? Revóquela: deja de funcionar en segundos.

Lista de IPs permitidas

Opcional, por cuenta: IPs exactas o rangos IPv4 CIDR (203.0.113.0/24). Otras IPs reciben 403 ip_not_allowed. Pídalo a su gestor de cuenta.

Sandbox

Las claves vld_test_ no analizan nada ni cobran, y devuelven resultados deterministas para que pueda probar cada camino de su código. Los objetos de test y live están separados por completo (también webhooks y eventos).

sandbox_outcomeo en reference / nombreResultado
approve (por defecto)—score 86 · approve
reviewreviewscore 58 · review · 1 desviación media
declinedeclinescore 28 · decline · 1 desviación alta
failfailstatus failed · screening.failed
La decisión sigue sus reglas de decisión, también en sandbox: si sube “aprobado desde” a 90, el 86 del sandbox pasa a review.

Peticiones y respuestas

Cuerpos en JSON (Content-Type: application/json). Fechas en ISO 8601 UTC; importes en céntimos (enteros). Cada respuesta lleva:

Validento-Request-IdInclúyalo cuando escriba a soporte.
Validento-VersionVersión de la API que respondió.
RateLimit-Limit / -Remaining / -ResetSu cupo por minuto.
Idempotent-Replayed: trueRespuesta repetida de una Idempotency-Key.

Idempotencia

Envíe Idempotency-Key: <uuid> en cada POST. Si la red falla y reintenta con la misma clave en 24 h, recibe la respuesta original y no se crea un duplicado. La misma clave con otro cuerpo devuelve 409 idempotency_conflict. El SDK lo hace por usted.

Paginación

Las listas devuelven { object:"list", data:[…], has_more }, de más nuevo a más antiguo. Parámetros: limit (1–100), starting_after=<id> (siguiente página), ending_before=<id> (anterior), created[gte] y created[lte] (segundos unix o ISO 8601).

curl -G https://api.validento.com/v1/screenings \
  -H "Authorization: Bearer vld_test_YOUR_SANDBOX_KEY" \
  -d limit=100 -d status=completed -d "created[gte]=1759276800" \
  -d "metadata[customer_id]=c_981"

Metadata

Guarde sus propios IDs en metadata (hasta 20 claves de ≤ 40 caracteres, valores string ≤ 500). Se devuelve tal cual, viaja en los webhooks y puede filtrar con metadata[clave]=valor.

Versiones y cambios

v1 no se rompe. Añadimos campos, endpoints, eventos y valores de enum sin aviso: ignore lo que no conozca. Un cambio incompatible recibe una versión con fecha nueva, con al menos 12 meses de transición y aviso por email.

Errores

Los errores usan códigos HTTP y un cuerpo estable. Programe contra error.code (estable), no contra el mensaje.

JSON
{
  "error": {
    "type": "invalid_request_error",
    "code": "consent_required",
    "message": "\"consent_confirmed\": true is required — confirm the applicant agreed to the check.",
    "param": "consent_confirmed",
    "doc_url": "https://validento.com/developers#error-consent_required",
    "request_id": "req_Fq9MsetWX27BncBC"
  }
}

Reintente con seguridad (misma Idempotency-Key) en 429, 500 y errores de red. No reintente otros 4xx sin cambiar la petición.

invalid_api_key 401 authentication_error

Clave ausente, mal escrita, revocada o caducada. → Compruebe la cabecera Authorization: Bearer vld_…

missing_scope 403 permission_error

La clave es restringida y no tiene este permiso. → Use otra clave o cree una con el permiso indicado en el mensaje.

ip_not_allowed 403 permission_error

La IP no está en su lista de IPs permitidas. → Añada la IP de salida de su servidor en el panel.

live_not_enabled 403 permission_error

El acceso live aún no está activado. → Siga con sandbox; su gestor activa live tras la revisión.

account_suspended 403 permission_error

Cuenta suspendida. → Contacte con su gestor de cuenta.

service_not_enabled 403 permission_error

El servicio no está en su acuerdo. → Pídalo a su gestor de cuenta.

insufficient_balance 402 billing_error

Saldo prepago insuficiente. → Recargue o active la recarga automática.

credit_limit_reached 402 billing_error

Límite de crédito alcanzado. → Pague la factura abierta o pida un límite mayor.

rate_limited 429 rate_limit_error

Demasiadas peticiones. → Espere los segundos de Retry-After y reintente.

invalid_json 400 invalid_request_error

El cuerpo no es JSON válido. → Envíe Content-Type: application/json y un objeto JSON.

invalid_parameter 400 invalid_request_error

Un parámetro no es válido (ver param). → Corrija el campo indicado en error.param.

invalid_purpose 400 invalid_request_error

purpose desconocido. → Use client_onboarding, employment, rental, purchase, business_partner o civil_matter.

invalid_metadata 400 invalid_request_error

metadata no cumple los límites. → Máx. 20 claves de ≤ 40 caracteres, valores string ≤ 500.

applicant_required 400 invalid_request_error

Falta applicant.name.

documents_required 400 invalid_request_error

Sin documentos. → Envíe de 1 a 20 documentos.

too_many_documents 400 invalid_request_error

Más de 20 documentos. → Divida el caso o combine páginas en un PDF.

invalid_document 400 invalid_request_error

Documento sin url ni data+media_type.

unsupported_media_type 415 invalid_request_error

Formato no admitido. → PDF, JPEG, PNG o WebP.

document_too_large 413 invalid_request_error

Un documento pasa de 10 MB. → Comprima la imagen o reduzca la resolución.

documents_too_large 413 invalid_request_error

Los documentos pasan de 20 MB en total.

document_url_unreachable 422 invalid_request_error

No pudimos descargar una URL (15 s). → Use una URL firmada válida ≥ 10 min, o envíe base64.

invalid_settings 400 invalid_request_error

Ajustes no válidos (ver mensaje).

invalid_url 400 invalid_request_error

La URL debe empezar por https://.

too_many_endpoints 409 invalid_request_error

Máximo 10 endpoints.

idempotency_conflict 409 idempotency_error

Idempotency-Key reutilizada con otro cuerpo. → Genere una clave nueva por operación.

not_found 404 invalid_request_error

El objeto no existe (o es de otro entorno). → Las claves test no ven objetos live y viceversa.

method_not_allowed 405 invalid_request_error

Método no permitido en esta ruta.

server_error 500 api_error

Error nuestro. → Es seguro reintentar (con la misma Idempotency-Key).

Límites

Peticiones por clave120 / min live · 60 / min sandbox · ampliable bajo petición
Documentos por comprobación1–20 · ≤ 10 MB cada uno · ≤ 20 MB en total
FormatosPDF, JPEG, PNG, WebP
Descarga de url15 s por documento
Webhook endpoints10 por cuenta · respuesta en 10 s
Eventos consultables30 días
Conservación de comprobacionessegún su contrato (por defecto 365 días); después se borran solas

Al pasar el límite: 429 rate_limited con Retry-After. Para cargas masivas, distribuya las peticiones o pida un límite mayor.

Comprobaciones

Una comprobación = una persona (o empresa) con 1 a 20 documentos. Es asíncrona: se crea con status: "processing" y termina en completed o failed. Solo se cobran las comprobaciones live completadas.

Crear una comprobación

POST/v1/screeningsscreenings:write
applicant.name stringobligatorio

Nombre de la persona (o empresa).

applicant.email / phone / date_of_birth / id_number / company / address / country string

Más datos ayudan al cruce de identidad. date_of_birth en YYYY-MM-DD, country ISO alpha-2.

documents[] arrayobligatorio

1–20 objetos: { url } (https, lo descargamos) o { data, media_type } (base64). type opcional como pista: payslip, bank_statement, id, employment_contract, tax_return, rental_contract, purchase_agreement, registration_docs, annual_accounts…

consent_confirmed trueobligatorio

Usted confirma que la persona aceptó la comprobación.

purpose enum

client_onboarding (KYC) · employment (contratación) · rental · purchase · business_partner · civil_matter. Cambia qué se valora: identidad y origen de fondos en un alta, historial laboral en una contratación, ingresos en un alquiler. Por defecto: su ajuste.

country string

País de los documentos (ISO alpha-2). Mejora la extracción.

case_details object

Hechos que el motor compara con los documentos: empleador, dirección, alquiler, precio, origen de fondos declarado… Cada diferencia sale como desviación. Plano, ≤ 30 claves snake_case. Ej.: { "monthly_rent": 1200, "employer": "Acme SL" }

reference string

Su propio ID (≤ 120). Filtrable.

metadata object

Ver metadata.

lang en | es

Idioma del resumen y de las desviaciones.

sandbox_outcome enum

Solo sandbox: approve, review, decline, fail.

curl https://api.validento.com/v1/screenings \
  -H "Authorization: Bearer vld_test_YOUR_SANDBOX_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "applicant": { "name": "Ana García", "email": "ana@example.com" },
    "purpose": "client_onboarding",
    "country": "ES",
    "reference": "case-1042",
    "consent_confirmed": true,
    "case_details": { "source_of_funds": "salary", "employer": "Acme SL" },
    "documents": [
      { "type": "payslip", "url": "https://files.yourapp.com/signed/payslip-sept.pdf" },
      { "type": "bank_statement", "media_type": "application/pdf", "data": "JVBERi0xLjQK..." }
    ],
    "metadata": { "customer_id": "c_981" }
  }'

Respuesta 202 con el objeto en processing. Use siempre Idempotency-Key.

El objeto screening

JSON
{
  "id": "6c1f6a2e-4b1d-4f7e-9c55-2a8f0d7b3e11",
  "object": "screening",
  "environment": "live",
  "status": "completed",
  "channel": "api",
  "reference": "case-1042",
  "purpose": "client_onboarding",
  "country": "ES",
  "applicant": { "name": "Ana García", "email": "ana@example.com" },
  "document_count": 3,
  "decision": "approve",
  "score": 82,
  "result": {
    "score": 82,
    "decision": "approve",
    "display_score": "82/100",
    "summary": "Documents are consistent; net income matches the bank statements.",
    "detected_document_type": "payslip",
    "detected_country": "ES",
    "documents_checked": 3,
    "deviations": [
      { "field": "employer_name", "severity": "low", "note": "Abbreviated on one payslip" }
    ],
    "fields": [ { "name": "net_monthly_income", "value": "3180.00" } ],
    "income": { "monthly_amount": 3180, "currency": "EUR" },
    "breakdown": { "document_integrity": 88, "financial_capacity": 79, "identity": 84 }
  },
  "case_details": { "employer": "Acme SL" },
  "error": null,
  "metadata": { "customer_id": "c_981" },
  "link_id": null,
  "created_at": "2026-10-04T09:12:03.120Z",
  "completed_at": "2026-10-04T09:12:41.877Z"
}
score 0–100

Siempre la misma escala, sus reglas deciden.

decision approve | review | decline

Según sus reglas de decisión (por defecto ≥ 70 / ≥ 45).

result.deviations[] array

Lo que no cuadra: entre documentos, con case_details o señales de manipulación. severity low/medium/high.

result.fields[] array

Datos extraídos (empleador, neto, IBAN parcial, fechas…).

result.income object

Ingreso mensual detectado y moneda.

result.breakdown object

Subpuntuaciones 0–100: integridad documental, capacidad financiera, identidad.

result.display_score string

La puntuación en su escala (82/100, 8.2/10 o B).

error string | null

Si failed: engine_unavailable u otro motivo. No se cobra; puede repetir.

Qué partes de result recibe lo decide usted en result_format.

Listar y filtrar

GET/v1/screeningsscreenings:read

Filtros: reference, status, decision, purpose, channel (api/link/dashboard), link_id, metadata[clave], created[gte|lte] + paginación.

Obtener, informe y borrar

GET/v1/screenings/{id}screenings:read
GET/v1/screenings/{id}/report?lang=enscreenings:read

Informe HTML imprimible con su marca. Conviértalo en PDF con cualquier navegador o Chrome headless (Puppeteer: page.pdf()).

DELETE/v1/screenings/{id}screenings:write

Borrado definitivo (RGPD): elimina la comprobación y los datos de la persona en su enlace; el uso facturado se conserva sin datos personales. Emite screening.deleted.

Verificación de identidad (ValiD)

Envíe a una persona un enlace: en su móvil fotografía su documento y hace un breve escaneo facial en vivo. Comprobamos los dígitos de control MRZ (ICAO 9303), la caducidad, la coincidencia facial y la presencia. No guardamos imágenes; usted recibe la decisión y un informe con las cifras.

POST/v1/id-checksid_checks:write
applicant.name stringobligatorio

Como en el documento (mín. 3 caracteres).

applicant.email stringobligatorio

Para el email con el enlace y el recibo.

purpose string

Para qué es; la persona lo ve.

reference string

Su id (CRM, expediente); vuelve en cada evento.

send_email boolean

Le enviamos el enlace en su nombre. Si no, use url (solo en esta respuesta).

locale es | en

Idioma del email y de la página.

expires_in_days integer

1–30, por defecto 14.

metadata object

Hasta 20 pares clave/valor.

curl https://api.validento.com/v1/id-checks \
  -H "Authorization: Bearer vld_test_YOUR_SANDBOX_KEY" \
  -H "Content-Type: application/json" \
  -d '{"applicant":{"name":"Ana García","email":"ana@example.com"},"purpose":"New client — file 1042","reference":"crm-1042","send_email":true,"locale":"es"}'
statusSignificado
pendingEsperando a la persona.
retryUn intento falló (foto, caducidad, cara); puede repetir hasta 3 veces.
in_reviewUn especialista de Validento decide desde el informe — nunca un rechazo automático por una foto mala.
passed / rejectedDecisión final (evento id_check.completed).
canceled / expiredCancelada, o no terminada a tiempo.
GET/v1/id-checksid_checks:read

Filtros: status, reference, metadata[clave] + paginación.

GET/v1/id-checks/{id}id_checks:read
POST/v1/id-checks/{id}/cancelid_checks:write
POST/v1/id-checks/{id}/simulateid_checks:write

Sandbox: con una clave vld_test_…, simulate con {"outcome":"passed"} (o retry, in_review, rejected) juega el resultado sin persona y envía su webhook. Facturación: una comprobación del mes cuando la persona envía su primer intento (live).

Sanciones y PEP

Compruebe una persona o empresa frente a las listas internacionales de sanciones (ONU, UE, OFAC de EE. UU., Reino Unido y muchas más), personas con responsabilidad pública (PEP) y listas de vigilancia penal, con datos de OpenSanctions actualizados a diario. La respuesta llega al instante.

POST/v1/sanctions-screeningssanctions:write
subject.name stringobligatorio

Nombre completo de la persona o razón social.

subject.kind person | company

Por defecto person.

subject.birth_date string

YYYY o YYYY-MM-DD (persona). Reduce mucho las coincidencias falsas.

subject.nationality string

ISO 3166-1 alfa-2 (persona).

subject.country string

ISO 3166-1 alfa-2, jurisdicción (empresa).

subject.registration_number string

Número de registro mercantil (empresa).

reference string

Su id; vuelve en el objeto y en cada evento.

customer string

Su id de cliente (Customers).

metadata object

Hasta 20 pares clave/valor.

curl https://api.validento.com/v1/sanctions-screenings \
  -H "Authorization: Bearer vld_test_YOUR_SANDBOX_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: crm-1042-sanctions" \
  -d '{"subject":{"kind":"person","name":"Ana García López","birth_date":"1986-03-14","nationality":"ES"},"reference":"crm-1042"}'
statusSignificado
clearNinguna coincidencia por encima del umbral.
in_reviewUn nombre coincide con una entrada de una lista. No es una conclusión: un especialista de Validento compara fecha de nacimiento, país y otros datos, normalmente en un día laborable. Mientras tanto, no tome decisiones negativas solo por esto.
no_matchRevisado: no es la misma persona o empresa (con nota en review.note).
confirmed_matchRevisado: la coincidencia se confirma. Siga sus propios procedimientos (p. ej. su oficial de cumplimiento).
failedNo se pudo consultar las listas; no se factura. Reintente (con la misma Idempotency-Key no se duplica).

result.hits lista las entradas parecidas: caption, score (0–1), topics (p. ej. sanction, role.pep, crime), datasets, countries, birth_dates y un url público. result.sanctioned y result.pep resumen las coincidencias.

GET/v1/sanctions-screeningssanctions:read

Filtros: status, reference, customer, metadata[clave] + paginación.

GET/v1/sanctions-screenings/{id}sanctions:read

Cómo integrarlo

  1. Llame al endpoint en el alta (y, si lo necesita, de nuevo periódicamente: las listas cambian a diario).
  2. clear → continúe. in_review → ponga el expediente en espera.
  3. Escuche el webhook sanctions_screening.reviewed: data.status es no_match o confirmed_match.
  4. Guarde el id en su expediente KYC como evidencia (fecha, listas, decisión).

Facturación: cada comprobación live es una unidad de su uso Enterprise (no se factura si failed). Sandbox: con una clave vld_test_… no se consultan listas; un nombre que contiene «match» simula una posible coincidencia (in_review), cualquier otro da clear. Permisos: sanctions:read / sanctions:write.

Webhooks

Le enviamos un POST firmado cuando algo cambia. Cada entorno tiene sus propios endpoints.

EventoCuándo
screening.createdComprobación creada (status processing).
screening.completedResultado disponible: score, decision, result.
screening.failedNo se pudo completar (no se cobra).
screening.deletedBorrada (RGPD) vía API o panel.
link.createdEnlace de verificación creado.
link.completedLa persona envió sus documentos; data.screening_id.
link.canceledEnlace cancelado.
link.expiredEl enlace caducó sin usarse.
id_check.createdVerificación de identidad creada (también desde el panel).
id_check.completedDecisión final: data.status passed o rejected (también tras revisión).
id_check.retryUn intento falló; la persona puede repetir (data.attempts_left).
id_check.in_reviewUn especialista decide desde el informe.
id_check.canceledVerificación cancelada.
sanctions_screening.completedComprobación de sanciones hecha: data.status clear o in_review.
sanctions_screening.reviewedUn especialista decidió una posible coincidencia: data.status no_match o confirmed_match.
sanctions_screening.failedNo se pudieron consultar las listas (no facturado).
pingPrueba desde el panel o la API.
HTTP
POST /your/webhook HTTP/1.1
Content-Type: application/json
Validento-Signature: t=1759569161,v1=5f2b0c8e…
Validento-Event: screening.completed
Validento-Event-Id: evt_8sK2pQ…
Validento-Delivery: 2b1c…
Validento-Version: 2026-10-01
{
  "id": "evt_8sK2pQ…",
  "object": "event",
  "type": "screening.completed",
  "environment": "live",
  "api_version": "2026-10-01",
  "created": 1759569161,
  "data": { "id": "6c1f6a2e-…", "object": "screening", "status": "completed", "decision": "approve", "score": 82, "…": "…" }
}

Verificar la firma

v1 = HMAC-SHA256 en hex de "{t}.{cuerpo crudo}" con su secreto whsec_…. Use el cuerpo exacto recibido (no lo vuelva a serializar), compare en tiempo constante y rechace timestamps de más de 5 minutos.

# Go
func verify(raw []byte, header, secret string) bool {
  var t, v1 string
  for _, p := range strings.Split(header, ",") {
    kv := strings.SplitN(p, "=", 2)
    if len(kv) == 2 && kv[0] == "t" { t = kv[1] }
    if len(kv) == 2 && kv[0] == "v1" { v1 = kv[1] }
  }
  mac := hmac.New(sha256.New, []byte(secret))
  mac.Write([]byte(t + "."))
  mac.Write(raw)
  ts, _ := strconv.ParseInt(t, 10, 64)
  return hmac.Equal([]byte(hex.EncodeToString(mac.Sum(nil))), []byte(v1)) && math.Abs(float64(time.Now().Unix()-ts)) <= 300
}

Entrega y reintentos

  • Responda 2xx en menos de 10 s; procese después (cola).
  • Si no: reintentos tras 1, 5, 30, 120, 360, 720 y 1440 minutos (~1 día).
  • Entrega “al menos una vez” y sin orden garantizado: deduplique por event.id y, si importa el estado, consulte el objeto con GET.
  • ¿Su endpoint estuvo caído? Recupere con GET /v1/events y reenvíe con POST /v1/events/{id}/resend.
  • Cada entrega e intento aparece en el panel (Desarrolladores → Webhooks), con botón de reenvío.

Gestionar endpoints por API

GET/v1/webhook-endpointswebhooks:read
POST/v1/webhook-endpointswebhooks:write
PATCH/v1/webhook-endpoints/{id}webhooks:write
DELETE/v1/webhook-endpoints/{id}webhooks:write
POST/v1/webhook-endpoints/{id}/roll-secretwebhooks:write
POST/v1/webhook-endpoints/{id}/testwebhooks:write
curl https://api.validento.com/v1/webhook-endpoints \
  -H "Authorization: Bearer vld_test_YOUR_SANDBOX_KEY" -H "Content-Type: application/json" \
  -d '{ "url": "https://api.yourapp.com/webhooks/validento", "events": ["screening.completed", "screening.failed", "link.completed"] }'
# → { "id": "…", "secret": "whsec_…" }   (the secret is shown once)

Eventos

Cada evento se guarda 30 días, tenga o no endpoints. Úselos para conciliar, recuperar caídas o construir sin webhooks.

GET/v1/events?type=screening.completed,link.completedevents:read
GET/v1/events/{id}events:read
POST/v1/events/{id}/resendwebhooks:write

resend entrega de nuevo a todos los endpoints suscritos, o a uno con { "endpoint_id": "…" } (aunque no esté suscrito).

curl -G https://api.validento.com/v1/events -H "Authorization: Bearer vld_test_YOUR_SANDBOX_KEY" \
  -d type=screening.completed -d "created[gte]=1759569000" -d limit=100

Ajustes

Sus reglas y su marca, por API o en el panel (Business → Ajustes). Valen para live y sandbox. Envíe solo lo que cambia; null restablece un campo.

GET/v1/settingssettings:read
PATCH/v1/settingssettings:write
decision.approve_min / review_min 1–100

Umbrales de la decisión (por defecto 70 / 45).

branding.display_name / logo_url / primary_color / support_email / privacy_url string

Su marca en la página de subida, emails e informes.

branding.hide_powered_by boolean

Oculta “con la tecnología de Validento”.

link_defaults.* object

purpose, country, expiry_days, documents_requested, redirect_url, email_applicant, language.

result_format.summary / deviations / fields / income / breakdown / applicant boolean

Qué partes recibe por API y webhooks.

result_format.score_scale 100 | 10 | grade

Formato de display_score.

notifications.recipients / on_review / on_decline / on_failed / on_completed

Emails a su equipo por comprobación live.

curl -X PATCH https://api.validento.com/v1/settings \
  -H "Authorization: Bearer vld_test_YOUR_SANDBOX_KEY" -H "Content-Type: application/json" \
  -d '{ "decision": { "approve_min": 75 }, "result_format": { "fields": false, "score_scale": "10" }, "branding": { "primary_color": "#6D28D9" } }'

Uso y facturas

GET/v1/usageusage:read

Periodo actual (del 20 al 19), comprobaciones, importe por tramos, mínimo, saldo (prepago) o límite de crédito (factura).

GET/v1/invoicesusage:read

Facturas y extractos mensuales con enlace a la factura de Stripe y su PDF.

Sus clientes (multi-tenant)

Para software que verifica en nombre de sus propios clientes — plataformas de KYC y cumplimiento, ATS y agencias de selección, aseguradoras con corredores, software para despachos. Registre cada cliente una vez y etiquete cada comprobación, enlace, verificación de identidad y webhook con customer. Cada cliente tiene su marca, sus webhooks, su consumo y su borrado.

POST/v1/customerscustomers:write
id stringobligatorio

Su propio id del cliente (1–64; letras, dígitos, _ . -). Es lo que pasa después en customer.

name stringobligatorio

Nombre (≤ 120).

brand_name / logo_url / primary_color / support_email string

Marca de ese cliente en la página de subida, los emails y el informe. Lo que no indique hereda su marca de cuenta.

metadata object

Sus propios datos (≤ 20 claves).

curl https://api.validento.com/v1/customers \
  -H "Authorization: Bearer vld_test_YOUR_SANDBOX_KEY" \
  -H "Content-Type: application/json" \
  -d '{"id":"acme","name":"Acme Lettings Ltd","brand_name":"Acme","primary_color":"#1D4ED8","support_email":"help@acme.example"}'

A partir de ahí, en cada POST /v1/screenings, /v1/verification-links, /v1/id-checks y /v1/webhook-endpoints: "customer": "acme". Un cliente desconocido devuelve unknown_customer. Los objetos devuelven customer y las listas filtran con ?customer=acme.

MarcaLa página de subida, el email con el enlace y el informe llevan la marca del cliente (brand_name, logo, color, email de soporte). Sin ella, la suya.
WebhooksUn endpoint creado con customer recibe solo los eventos de ese cliente (hasta 200 endpoints así). Los endpoints sin cliente reciben todo; el evento lleva data.customer.
ConsumoGET /v1/customers/{id} devuelve usage: comprobaciones completadas este periodo y en total — para facturar a su cliente.
BorradoPOST /v1/customers/{id}/erase elimina todas sus comprobaciones, enlaces y verificaciones de identidad (RGPD, irreversible). DELETE elimina solo la ficha del cliente.
GET/v1/customerscustomers:read
GET/v1/customers/{id}customers:read
PATCH/v1/customers/{id}customers:write
DELETE/v1/customers/{id}customers:write
POST/v1/customers/{id}/erasecustomers:write
Claves con permisos: customers:read y customers:write. Una clave por cliente final no hace falta: etiquete con customer y filtre.

Zapier

Conecte Validento con más de 7.000 apps sin programar: cuando termina una comprobación, actualice su CRM, avise en Slack o guarde el resultado en una hoja de cálculo; cuando entra un candidato, envíele un enlace de verificación.

App de Validento para Zapier

Disparadores (al instante)Screening Completed · Screening Failed · Verification Link Completed · Verification Link Expired · ID Check Completed · Sanctions Screening Completed · Sanctions Screening Reviewed
AccionesCreate Verification Link · Create ID Check · Screen for Sanctions & PEP
BúsquedaFind Screening (por id o por su referencia)
ConexiónUna clave API (vld_test_… para probar gratis).

La app está en acceso por invitación: pídanos el enlace en info@validento.com. Cada Zap activo crea un endpoint de webhook para su evento (máx. 10 por cuenta).

Sin la app: Webhooks by Zapier

  1. Disparador

    En Zapier elija Webhooks by Zapier → Catch Hook y copie la URL.

  2. Endpoint

    Panel Enterprise → Desarrolladores → Webhooks → pegue la URL y elija los eventos. Pulse “Probar” para que Zapier vea un ejemplo.

  3. Campos

    El objeto está en data: data.score, data.decision, data.reference, data.metadata.*.

  4. Acciones hacia Validento

    Webhooks by Zapier → Custom Request: POST ${API}/v1/verification-links con la cabecera Authorization: Bearer vld_….

Webhooks by Zapier requiere un plan de pago de Zapier.

Make

En Make (antes Integromat) no hace falta una app: use los módulos estándar.

  1. Recibir resultados

    Módulo Webhooks → Custom webhook → copie la URL → regístrela en el panel (Desarrolladores → Webhooks) → “Probar” para que Make detecte la estructura.

  2. Llamar a la API

    Módulo HTTP → Make a request: URL ${API}/v1/…, cabecera Authorization: Bearer vld_…, cuerpo JSON. Marque “Parse response”.

  3. Filtrar

    Ponga un filtro en type (p. ej. screening.completed) si el endpoint recibe varios eventos.

Cuerpo de “Make a request” → POST /v1/verification-links
{
  "applicant": { "name": "{{1.name}}", "email": "{{1.email}}" },
  "purpose": "client_onboarding",
  "reference": "{{1.deal_id}}",
  "send_email": true,
  "metadata": { "source": "make" }
}

CRM: Pipedrive, Salesforce, HubSpot

Hoy los CRM se conectan a través de Zapier o Make (ambos tienen apps oficiales de Pipedrive, Salesforce y HubSpot). La clave es la referencia: ponga el id del trato o contacto de su CRM en reference (o en metadata) al crear el enlace o la comprobación; vuelve en cada evento.

PipedriveTrato en etapa “Verificar” → Create Verification Link (reference = id del trato). Screening Completed → Pipedrive “Add note” / “Update deal” con score y decisión.
SalesforceNuevo Lead/Opportunity → Create Verification Link. Screening Completed → “Update record” (campos propios: Validento Score, Decision, Report link).
HubSpotIgual: la propiedad del contacto o del negocio se actualiza con el resultado.

Conectores nativos (sin Zapier/Make) en el Marketplace de Pipedrive o en Salesforce AppExchange: en la hoja de ruta.

ATS y selección

Para equipos de RR. HH., agencias de selección y plataformas de contratación: verifique identidad, documentos e historial laboral de un candidato de otro país antes de la oferta. La referencia es el id del candidato o de la vacante en su ATS; el resultado vuelve por webhook a ese registro.

FlujoCandidato pasa a “Verificación” → POST /v1/verification-links con purpose: "employment", documents_requested (DNI o pasaporte, última nómina, carta de empleo, titulación) y send_email: true. El candidato sube en una página con su marca. screening.completed → nota o campo en el candidato.
IdentidadAñada POST /v1/id-checks (ValiD): el candidato verifica su documento y su cara en el móvil; sin imágenes guardadas.
Agencias¿Verifica para varios empleadores? Registre cada uno como cliente: su marca en la página del candidato, sus webhooks y su consumo.
Greenhouse · Lever · Workable · Teamtailor · RecruiteeHoy a través de Zapier o Make (todos tienen app oficial): disparador “candidato cambia de fase” → Create Verification Link; Screening Completed → “Add note” o campo personalizado.
Cuerpo → POST /v1/verification-links
{
  "customer": "{{employer_id}}",
  "purpose": "employment",
  "applicant": { "name": "{{candidate.name}}", "email": "{{candidate.email}}" },
  "documents_requested": ["ID or passport", "Last payslip", "Employment letter", "Diploma"],
  "reference": "{{candidate.id}}",
  "send_email": true,
  "redirect_url": "https://careers.yourcompany.com/verified"
}

Despliegue privado (on-premise)

Para clientes que no pueden enviar documentos fuera de su propia infraestructura: los contenedores de análisis de Validento, ejecutados por usted. Licencia anual, mismas respuestas que la API, actualizaciones como nuevas imágenes.

verify-serviceAnálisis de documentos e ingresos. Se ejecuta en su proyecto de Google Cloud y usa su Vertex AI (su región, sus condiciones de tratamiento). Validento nunca ve los documentos.
idv-service (ValiD)Identidad: documento, cara y presencia en vivo. Totalmente offline: modelos abiertos dentro de la imagen, sin ninguna llamada saliente salvo el heartbeat opcional. 2 vCPU, 4 GB, sin GPU.
LicenciaUn token firmado (Ed25519) en VALIDENTO_LICENSE + la clave pública en VALIDENTO_LICENSE_PUBKEY. Se verifica offline al arrancar; sin token válido el contenedor no arranca; al caducar responde 403 license_inactive. Aviso en el log desde 30 días antes.
HeartbeatOpcional, por licencia: una vez al día el contenedor envía { license_id, product, version, instance } — nunca documentos, imágenes ni resultados. Permite a Validento revocar una licencia. Sin heartbeat, ninguna llamada saliente.
Imágeneseurope-west4-docker.pkg.dev/validento-com/private/<service>:<tag> — registro privado; su cuenta de servicio recibe acceso de lectura. Etiquetas YYYY.MM; fije una en producción.
verify-service
docker run -d -p 8080:8080 \
  -e VALIDENTO_LICENSE="vdl1.…" -e VALIDENTO_LICENSE_PUBKEY="…" \
  -e GOOGLE_CLOUD_PROJECT="your-gcp-project" -e GOOGLE_CLOUD_LOCATION="europe-west4" \
  -e GOOGLE_APPLICATION_CREDENTIALS=/secrets/sa.json -v /path/sa.json:/secrets/sa.json:ro \
  -e VERIFY_API_KEY="a-long-random-string" \
  europe-west4-docker.pkg.dev/validento-com/private/verify-service:2026.10
curl -X POST http://localhost:8080/verify -H "apikey: a-long-random-string" -H "Content-Type: application/json" \
  -d '{"purpose":"client_onboarding","country":"ES","lang":"en","files":[{"media_type":"application/pdf","data":"<base64>"}]}'
idv-service (ValiD)
docker run -d -p 8081:8080 \
  -e VALIDENTO_LICENSE="vdl1.…" -e VALIDENTO_LICENSE_PUBKEY="…" \
  -e IDV_API_KEY="another-long-random-string" -e IDV_SESSION_SECRET="$(openssl rand -hex 32)" \
  europe-west4-docker.pkg.dev/validento-com/private/idv-service:2026.10
# POST /v1/session → challenges; POST /v1/check (document, selfie, frames) → { decision, signals }  — header x-api-key

POST /verify devuelve score, summary, detected_type, detected_country, fields[], deviations[], components, cross_check e ingresos detectados — la misma información que result en la API, sin la capa de cuenta (sin webhooks, enlaces ni panel: eso lo hace su sistema). GET /health en ambos.

Precio: licencia anual más un precio por comprobación, a medida, con contrato de soporte y confidencialidad. Hable con ventas: Enterprise. Guía completa y docker-compose en el paquete de entrega.

Socios de canal

Para empresas que ofrecen la verificación de Validento a sus propios clientes — software para despachos y asesorías, plataformas de KYC y onboarding, sistemas de selección (ATS) y nóminas, financieras y aseguradoras, plataformas de alquiler y software inmobiliario, marketplaces B2B. Una cuenta Enterprise, una API, su marca.

Su marcaLogo, colores y nombre en el panel (Ajustes); cada cliente puede tener la suya (brand_name, logo, color, email de soporte en su ficha de cliente).
Por cliente finalRegistre cada cliente final en /v1/customers y pase customer en cada llamada: marca, webhooks, consumo y borrado por cliente. Filtre con GET /v1/screenings?customer=acme.
En su productoEnlace por email, embed en su web o app, o envío directo de documentos por API.
ResultadosWebhooks firmados y informe con su marca para reenviar a su cliente.
FacturaciónUna factura mensual por volumen para usted; usted factura a sus clientes con el consumo de GET /v1/customers/{id}.

Aún no hay subcuentas con inicio de sesión propio para sus clientes finales; se separan por metadata. Hable con su gestor de cuenta para condiciones de canal.

SDK JavaScript

Un solo archivo, sin dependencias, para Node 18+, Deno, Bun y entornos edge. Reintentos con backoff (respeta Retry-After), Idempotency-Key automática, paginación con for await, errores tipados y verificación de webhooks. Tipos en validento.d.ts.

⬇ validento.mjs ⬇ validento.d.ts

TypeScript
import Validento, { ValidentoError } from './validento.mjs';   // Deno: 'https://validento.com/sdk/validento.mjs'
const vd = new Validento(process.env.VALIDENTO_KEY!, { maxRetries: 3, timeoutMs: 60_000 });
try {
  const s = await vd.screenings.create({
    applicant: { name: 'Ana García' }, consent_confirmed: true, purpose: 'purchase',
    documents: [{ url: signedUrl, type: 'payslip' }],
    case_details: { purchase_price: 320000 }, metadata: { customer_id: 'c_981' },
  });
  const done = await vd.screenings.waitFor(s.id);    // polling helper; prefer webhooks in production
  console.log(done.decision, done.result?.deviations);
} catch (err) {
  if (err instanceof ValidentoError) console.error(err.status, err.code, err.param, err.requestId);
  else throw err;
}
console.log(vd.lastResponse?.rateLimit);

¿Otro lenguaje? Genere un cliente desde la especificación OpenAPI 3.1 (openapi-generator, oapi-codegen, NSwag…) o impórtela en Postman / Insomnia.

Shell
# Postman: Import → Link → https://api.validento.com/v1/openapi.json
npx @openapitools/openapi-generator-cli generate -i https://api.validento.com/v1/openapi.json -g python -o ./validento-python
npx @openapitools/openapi-generator-cli generate -i https://api.validento.com/v1/openapi.json -g go -o ./validento-go

Seguridad y datos

  • TLS 1.2+ en todo. Claves guardadas como hash SHA-256; secretos de webhook nunca se vuelven a mostrar.
  • Análisis en la UE (Países Bajos); el resultado se guarda en EE. UU. (Supabase, Oregón) bajo el Marco de Privacidad de Datos UE-EE. UU. Los documentos se analizan y no se guardan.
  • Conservación según contrato (por defecto 365 días), borrado automático después; borrado inmediato con DELETE /v1/screenings/{id}.
  • Usted es responsable del tratamiento; Validento es encargado (DPA disponible). consent_confirmed registra la base de su comprobación.
  • Permisos por clave, lista de IPs, rotación con gracia, registro de cada petición (panel → Registro).
  • El resultado es una ayuda a la decisión, no asesoramiento legal ni una decisión automatizada final: mantenga una revisión humana para “review” y “decline”.

Changelog

2026-10-09 — Nuevo recurso Sanciones y PEP (OpenSanctions): POST /v1/sanctions-screenings, eventos sanctions_screening.*, permisos sanctions:*. Sin cambios incompatibles.

2026-10-09 — Despliegue privado: verify-service e idv-service como contenedores con licencia, ejecutados por el cliente.

2026-10-08 — purpose admite client_onboarding y employment. Nuevo recurso Customers (multi-tenant): customer en comprobaciones, enlaces, verificaciones de identidad y webhooks; marca, consumo y borrado por cliente. Sin cambios incompatibles.

2026-10-07
  • ValiD en la API: /v1/id-checks, eventos id_check.* y simulación en sandbox.
  • Guías de integración: Zapier (app por invitación), Make, CRM y socios de canal.
2026-10-01
  • Claves con permisos, API de eventos (30 días, reenvío), endpoints de webhook por API, cancelar y listar enlaces.
  • Hasta 20 documentos (20 MB), case_details, ajustes y formato de resultado, informe con su marca, borrado RGPD.
  • Cabeceras RateLimit-*, Validento-Version, Idempotent-Replayed; errores con param y doc_url; OpenAPI 3.1; SDK JavaScript.

Soporte

Escríbanos a info@validento.com con el Validento-Request-Id y la hora aproximada. Clientes Enterprise: también su gestor de cuenta. Respondemos en horario laboral europeo, normalmente el mismo día.

¿Aún no tiene cuenta? Vea Enterprise o contacte con ventas.