API v1 · Guía del integrador · 1.2.0
Integrar Valida por API
Esta guía es todo lo que necesita un desarrollador para integrarse sin hablar con nadie: cómo autenticarse, cómo reintentar sin cobrar dos veces, qué versión de lista consultó, cómo se mide el paquete, cuándo se bloquea el servicio (spoiler: nunca por consumo) y cómo recibir alertas. Cada endpoint trae ejemplos en curl, JavaScript y Python.
Base URL: https://api.valida.metrikone.co · Vigente desde: 9 de septiembre de 2026
Contenido de la guía16 secciones
1. Introducción
Valida expone una API REST sobre HTTPS para validar personas naturales y jurídicas contra listas SARLAFT. Cada consulta se persiste 10 años con hash de integridad y puede descargarse como PDF auditable. La API es servidor a servidor: la API key nunca debe vivir en un navegador ni en una app móvil.
- Base URL:
https://api.valida.metrikone.co. Todas las rutas empiezan por/api/v1/. - Formato: JSON UTF-8 en ambos sentidos, salvo los PDF (
application/pdf). - Timestamps: ISO 8601 en UTC (
2026-09-08T14:32:00Z). Los periodos de consumo van en fechas locales de Bogotá (2026-09-01). - Request id: toda respuesta trae
X-Valida-Request-Id. Guárdelo en sus logs; es lo primero que pide soporte. - CORS: las rutas
/api/v1/*responden preflight, pero exponer la key en un navegador va contra el contrato. Llame siempre desde su backend. - Sin rate limit por ritmo: hoy no existe un
429. Lo que sí existe es la guía de concurrencia; respétela.
Qué es y qué no es Valida
Valida es una herramienta tecnológica de consulta automatizada. No constituye asesoría jurídica ni sustituye el sistema SARLAFT/SAGRILAFT/SIPLAFT del sujeto obligado. El análisis de coincidencias, la decisión de vinculación y el reporte a la UIAF siguen siendo del oficial de cumplimiento. OFAC SDN, Unión Europea y US State Dept FTO se consultan como referencia: no son vinculantes en Colombia.
2. Quickstart en 5 pasos
- Reciba su API key. MeTRIK la entrega por un canal seguro. Guárdela como secreto de su backend (variable de entorno
VALIDA_API_KEY). No se puede recuperar; si se pierde, se rota. - Compruebe que llega.
curl -s https://api.valida.metrikone.co/api/v1/health - Haga su primera validación con una
Idempotency-Keydesde el día uno.Leacurl -s -X POST https://api.valida.metrikone.co/api/v1/validate \ -H "Authorization: Bearer $VALIDA_API_KEY" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: $(uuidgen)" \ -d '{ "tipo": "natural", "nombre": "Juan Perez Gomez", "documento": { "tipo": "CC", "numero": "1077089147" }, "referencia_externa": "EXP-2026-00123" }'severidad,matches[]ylistas_consultadas[]. Guardeconsulta_id. - Descargue el PDF auditable de esa consulta.
curl -s https://api.valida.metrikone.co/api/v1/reporte/<consulta_id> \ -H "Authorization: Bearer $VALIDA_API_KEY" -o reporte.pdf - Mire su consumo y configure alertas.La respuesta del
curl -s https://api.valida.metrikone.co/api/v1/cuenta/consumo -H "Authorization: Bearer $VALIDA_API_KEY" curl -s -X PUT https://api.valida.metrikone.co/api/v1/cuenta/alertas \ -H "Authorization: Bearer $VALIDA_API_KEY" -H "Content-Type: application/json" \ -d '{ "umbrales": [80, 100], "emails": ["cumplimiento@suempresa.co"], "webhook": { "url": "https://suempresa.co/valida/webhook" } }'PUTtraewebhook.secretuna sola vez. Guárdelo.
Si su cliente API opera para terceros (agregador)
Agregue sujeto_obligado: { "razon_social", "nit" } a cada consulta. Sin él recibe400 sujeto_obligado_requerido. El PDF se emite a nombre de ese sujeto obligado y usted queda como canal. Ver sujeto obligado final.
3. Autenticación y rotación de key
Toda ruta /api/v1/* exige Authorization: Bearer <api_key>. Valida guarda solo el hash SHA-256 de la key: nadie en MeTRIK puede leerla después de emitida.
Authorization: Bearer <api_key>
Content-Type: application/json- Key ausente, mal formada, revocada o de cliente inactivo:
401 invalid_api_keycon headerWWW-Authenticate: Bearer. - Rotación: escriba a soporte. Se emite una key nueva y la anterior sigue activa el tiempo que usted pida para hacer el cambio sin corte; luego se revoca. Hoy no hay endpoint de autoservicio para rotar.
- Una key por integración. Si varios sistemas suyos consultan, pida una key por sistema: permite revocar una sin tumbar las demás.
- Nunca la envíe en la URL, en un navegador ni en logs.
4. Idempotencia y reintentos
Cada POST /validate que se persiste es una consulta cobrable. Un timeout de su lado con un reintento a ciegas produce dos consultas cobradas. Para evitarlo, envíe siempre el header Idempotency-Key.
| Situación | Qué devuelve Valida |
|---|---|
Idempotency-Key | De 1 a 64 caracteres ASCII imprimibles, único por consulta. Recomendado: UUID v4. Vale 24 horas. |
| Misma clave + mismo cuerpo en 24 h | La respuesta original, mismo consulta_id, header X-Valida-Idempotent-Replay: true. No se cobra. |
| Misma clave + cuerpo distinto | 409 idempotency_error. Use otra clave. |
| Clave mal formada | 400 idempotency_key_invalida. |
| Respuesta 4xx o 5xx | No reserva la clave: puede reintentar con la misma. |
Reintentos recomendados
- Timeout del cliente: 60 segundos o más. Lo normal son 1-4 s, pero una consulta con muchos candidatos puede tardar más; el servidor corta a los 60 s.
- Reintente ante timeout, error de red y
500 persistencia_error, siempre con la mismaIdempotency-Key, con espera exponencial (2 s, 4 s, 8 s) y máximo 3 intentos. - No reintente
400,401,402ni409: la respuesta no va a cambiar hasta que usted cambie algo. - referencia_externa: mande su id de expediente o fila; se devuelve tal cual y luego puede buscarlo con
GET /consultas?referencia_externa=. Es para conciliar; no reemplaza la Idempotency-Key.
5. Listas, tiers y versión de lista
| Tier | Listas | Qué significa para usted |
|---|---|---|
1_vinculante | ONU Consolidated · CSN Colombia | Obligación legal explícita en Colombia. Un exacto aquí es un hallazgo alto. |
2_obligatoria | PEP Colombia (SIGEP) | Obligatoria de construir por el sujeto obligado. Un exacto es hallazgo medio: activa debida diligencia intensificada, no bloqueo. |
3_referencia | OFAC SDN · EU Consolidated Sanctions · US State Dept FTO | No vinculantes en Colombia. Estándar de facto de debida diligencia; su tratamiento lo define el manual SARLAFT de cada sujeto obligado. |
Valida descarga cada lista de su fuente oficial a diario y la versiona por hash. Cada respuesta declara contra qué versión se comparó y esa versión queda grabada con la consulta:
listas_consultadas[]en el cuerpo:slug,nombre,tier,version_id,hash_contenido,fetched_en,total_entradas.- Header
X-Valida-Listas-Version: onu_consolidated=2026-09-05T05:15:12Z;ofac_sdn=…. - El PDF de
/reporte/{consulta_id}imprime esas mismas versiones aunque lo descargue meses después. Nunca se recalcula.
Para el oficial de cumplimiento de su cliente
Guarde listas_consultadas junto con el resultado. Es la evidencia de que la verificación se hizo contra la lista vigente ese día.
6. Valida Diligencia (módulo aparte)
POST /v1/diligencia consulta antecedentes de fuentes nacionales para debida diligencia ampliada. Es un módulo distinto, no una lista más de SARLAFT, y por eso vive en su propio endpoint. Está en beta y se cobra aparte del paquete SARLAFT.
No mezcle los dos módulos
Un hallazgo de Diligencia no es un hallazgo SARLAFT. No entra en /validate, no aparece en listas_consultadas[], no sale en el PDF ni en el certificado mensual, y no descuenta del paquete SARLAFT. Cada respuesta viene sellada como REFERENCIA — decisión del cliente. Tratarlo como sanción LA/FT/FP ante un supervisor es un error de fondo del sujeto obligado.
| Fuente | Qué contiene | Qué NO es |
|---|---|---|
siri_procuraduria | Subconjunto certificable del SIRI publicado como dato abierto por la Procuraduría General de la Nación: sanciones disciplinarias e inhabilidades. | No equivale ni reemplaza al certificado de antecedentes disciplinarios que expide la Procuraduría. |
secop2_multas | Multas, sanciones e inhabilidades a contratistas en SECOP II (Ley 80/1993 y Ley 1150/2007). | Parte de los registros figura «A la espera de aprobación»: lea estado_plataforma antes de concluir. |
Ambas fuentes son datos abiertos de datos.gov.co bajo licencia CC BY-SA 4.0, se ingieren con el mismo cron diario y se versionan por hash igual que las listas SARLAFT. La respuesta trae fuentes_consultadas[] con la versión de cada una.
curl -X POST https://api.valida.metrikone.co/api/v1/diligencia \
-H "Authorization: Bearer $VALIDA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"documento": "1020304050",
"tipo_documento": "CC",
"nombre": "Juan Pérez Gómez",
"referencia_externa": "exp-4471"
}'{
"consulta_id": "…",
"modulo": "diligencia",
"tipo": "referencia",
"sello": "REFERENCIA — decisión del cliente",
"leyenda": "Información de referencia para debida diligencia. No constituye lista de sancionados LA/FT/FP ni hallazgo SARLAFT. La decisión es del cliente.",
"total_hallazgos": 1,
"fuentes_consultadas": [
{ "slug": "siri_procuraduria", "version_id": "…", "hash_contenido": "…", "fetched_en": "…" }
],
"hallazgos": [ { "fuente": "siri_procuraduria", "coincidencia_por": "documento", "score": 1 } ],
"hash_respuesta": "…",
"fecha_consulta": "…"
}- Autenticación: la misma api_key. No hay credencial aparte.
- Entrada:
documentoobligatorio (mínimo 5 caracteres);tipo_documento,nombreyreferencia_externaopcionales. - Errores: mismo contrato que el resto de la API (
error,message,doc_url,request_id). - Consumo: el contador y el cobro de Diligencia son independientes y todavía no están expuestos en
/cuenta/consumo. Mientras tanto, cada consulta queda registrada como facturable.
7. Sujeto obligado final (agregadores)
Si su plataforma consulta por cuenta de varias empresas (patrón agregador), el reporte no puede quedar a nombre de su plataforma: un supervisor concluiría que el obligado no consultó. Por eso existe sujeto_obligado.
| Campo | Regla |
|---|---|
sujeto_obligado.razon_social | Razón social legal del sujeto obligado final. 3 a 200 caracteres. |
sujeto_obligado.nit | NIT. Se aceptan puntos y guion con dígito de verificación ("800.123.456-7"); se guarda normalizado a dígitos. |
| Cuándo es obligatorio | Cuando su cliente API está marcado como opera para terceros. Si falta: 400 sujeto_obligado_requerido. Si no está marcado, es opcional y se estampa igual si lo envía. |
| Efecto en el PDF | La banda principal dice "Sujeto obligado: <razón social> — NIT" y debajo "A través de <su razón social> — NIT". El pie repite al sujeto obligado en cada página. |
| Búsqueda | GET /consultas?sujeto_obligado_nit=800123456 devuelve solo las consultas de ese sujeto obligado. |
{
"tipo": "juridica",
"nombre": "Acme Trading SAS",
"documento": { "tipo": "NIT", "numero": "900123456" },
"sujeto_obligado": { "razon_social": "Transportes La Sabana SAS", "nit": "800.123.456-7" },
"referencia_externa": "vinculacion-8841"
}8. Consumo y paquete
Su contrato es un paquete de consultas por mes calendario (America/Bogotá). Cuenta toda consulta que se persiste (una respuesta 200 de /validate que no sea replay). No hay rollover: lo que no se usa en el mes no pasa al siguiente.
| Paquete | Consultas/mes | Precio mes (COP + IVA) | Unitario | Excedente por consulta |
|---|---|---|---|---|
| 1K | 1.000 | $150.000 | $150 | $110 |
| 5K | 5.000 | $550.000 | $110 | $90 |
| 10K | 10.000 | $900.000 | $90 | $70 |
| 20K | 20.000 | $1.400.000 | $70 | $50 |
| A medida | +20.000 | Según contrato | Según contrato | $50 |
El excedente se cobra al unitario del escalón siguiente y entra en la cuenta del siguiente periodo.
Headers en cada respuesta de /validate
Van en el 200 y en los 4xx de negocio (400, 402, 409). Son la misma lectura que alimenta /cuenta/consumo: no cuestan una llamada extra.
X-Valida-Plan: 20K
X-Valida-Periodo-Inicio: 2026-09-01
X-Valida-Periodo-Fin: 2026-10-01
X-Valida-Consumo-Incluidas: 20000
X-Valida-Consumo-Consumidas: 16421
X-Valida-Consumo-Restante: 3579
X-Valida-Consumo-Excedente: 0
X-Valida-Consumo-Estado: ok | umbral_80 | agotado | excedente | bloqueado | sin_plan
X-Valida-Listas-Version: onu_consolidated=2026-09-05T05:15:12Z;ofac_sdn=2026-09-07T05:16:03Z;...Endpoints de cuenta
GET /api/v1/cuenta/consumo: plan, periodo, contador, excedente estimado, estado de cobro y política.409 sin_plan_asignadosi su cliente aún no tiene paquete (por ejemplo, una beta sin costo);/validatefunciona igual.GET /api/v1/cuenta/consumo/historial?periodos=6: periodos anteriores con consumidas, excedente y estado de cobro.
Al 100% no pasa nada malo
Valida no bloquea por consumo. La consulta 20.001 se procesa igual, se marca como excedente (X-Valida-Consumo-Estado: excedente) y se cobra al unitario del escalón siguiente. Un tope duro por consumo solo existe si su empresa lo pide por escrito.
9. Cobro y bloqueo por mora
En lenguaje claro: nunca se bloquea por consumo; solo por cuenta vencida sin pago. Así funciona el ciclo:
- Aviso de cobro. Cuando el consumo llega al 80% del paquete o cuando llega el día 20 del periodo (lo primero que ocurra), MeTRIK emite la cuenta de cobro del siguiente paquete. Usted recibe el evento
paquete.cobro_emitido(si configuró alertas) con la fecha de vencimiento. - Pago. Cuando MeTRIK registra el pago, recibe
paquete.reactivadosi estaba bloqueado. Si no lo estaba, no pasa nada visible: siguió consultando todo el tiempo. - Bloqueo. Solo si se cumplen las dos condiciones a la vez: la cuenta de cobro venció sin pago registrado y el consumo del periodo supera el 100% del paquete. Entonces
POST /validateresponde402 paquete_vencido_sin_pagoconX-Valida-Consumo-Estado: bloqueado. Las demás rutas (consultas, reportes, cuenta) siguen funcionando. - Reactivación. Se envía el soporte de pago a soporte. Al registrarlo, el siguiente
/validatevuelve a funcionar. Ninguna consulta se pierde: reintente las que recibieron 402 con su mismaIdempotency-Key.
{
"error": "paquete_vencido_sin_pago",
"message": "La cuenta de cobro del paquete esta vencida sin pago registrado y el consumo supera el paquete contratado. Registre el pago con soporte para reactivar; las consultas no se pierden.",
"doc_url": "https://app.valida.metrikone.co/docs#error-paquete_vencido_sin_pago",
"request_id": "req_3f9c1a2b4d5e6f708192a3b4",
"consumo": { "consumidas": 21340, "incluidas": 20000, "excedente": 1340, "estado": "bloqueado", ... },
"cobro": { "cuenta_vence_en": "2026-10-05T00:00:00Z", "cuenta_referencia": "CC-0042", "periodo": "2026-09-01" },
"como_reactivar": "Envie el soporte de pago a mauricio.moreno@metrik.com.co o al WhatsApp +57 315 950 9103. ..."
}Cómo programar el 402
Trátelo como un error de negocio, no de red: registre el request_id, avise a su área de cartera y no reintente en bucle. Puede sondear GET /cuenta/consumo (campo cobro.bloqueado) cada pocos minutos o esperar el evento paquete.reactivado.
10. Alertas y webhooks
Configure umbrales de consumo y canales (email y/o webhook). Por defecto los umbrales son 80 y 100 y no hay canal configurado: hasta que no ponga un email o una URL, no recibe nada.
| Ruta | Qué hace |
|---|---|
GET /cuenta/alertas | Configuración vigente y eventos del periodo (disparados con su estado de entrega, y pendientes). |
PUT /cuenta/alertas | Actualiza umbrales (1-200 %, máximo 6), emails, webhook.url (https) y activa. Los campos omitidos se conservan. Al configurar la URL por primera vez la respuesta trae webhook.secret una sola vez. |
POST /cuenta/alertas/webhook/rotar-secreto | Secreto nuevo (una sola vez). El anterior sigue firmando 24 h. |
POST /cuenta/alertas/prueba | Envía paquete.prueba a sus canales y devuelve el evento_id y el resultado del primer intento. |
Eventos
| Evento | Cuándo | Idempotencia |
|---|---|---|
paquete.umbral_alcanzado | Primera consulta del periodo que cruza cada umbral < 100 que usted configuró. | Una vez por (periodo, umbral). |
paquete.agotado | Primera consulta que cruza el 100%. | Una vez por periodo. |
paquete.excedente | Cada umbral > 100 configurado (110, 120, 150…). | Una vez por (periodo, umbral). |
paquete.renovado | Primera consulta del periodo nuevo: el contador volvió a cero. | Una vez por periodo. |
paquete.cobro_emitido | MeTRIK marcó la cuenta de cobro del siguiente paquete, con vencimiento. | Una vez por periodo. |
paquete.bloqueado | La primera consulta que recibe 402 en el periodo. | Una vez por periodo. |
paquete.reactivado | Se registró el pago y el bloqueo se levantó. | Puede repetirse. |
paquete.prueba | A petición. | Puede repetirse. |
Entrega
POSTJSON a su URL, timeout 10 s. Éxito = cualquier2xx. Responda rápido y procese después.- Reintentos con espera 1 min, 5 min, 30 min, 2 h, 12 h, 24 h. Tras 6 fallos el evento queda
fallido(visible enGET /cuenta/alertas). - El email se envía en paralelo al webhook, una vez por evento.
- Headers:
X-Valida-Event(tipo),X-Valida-Delivery-Id(cambia en cada intento),X-Valida-Signature. - Deduplique por
iddel cuerpo: puede recibir el mismo evento más de una vez.
{
"id": "0d6f2c3a-5b1e-4e8a-9c7d-2f1a3b4c5d6e",
"tipo": "paquete.agotado",
"creado_en": "2026-09-18T15:41:02Z",
"version": "2026-09-01",
"cliente_id": "55a4400c-...",
"periodo": { "inicio": "2026-09-01", "fin": "2026-10-01" },
"umbral": 100,
"consumo": { "consumidas": 20000, "incluidas": 20000, "restantes": 0, "porcentaje": 100, "excedente": 0, "excedente_precio_unitario": 50 },
"plan": { "codigo": "20K", "consultas_incluidas": 20000 },
"politica": { "bloqueo_por_consumo": false, "bloqueo_por_mora": true, "rollover": false },
"consulta_id_detonante": "c0a8..."
}Verificar la firma
X-Valida-Signature: t=1758210062,v1=<hex>. La firma es hex(HMAC-SHA256(secret, t + "." + cuerpo_crudo)). Durante las 24 h siguientes a una rotación hay dos v1: acepte si cualquiera coincide. Compare en tiempo constante y rechace si|ahora − t| > 300 s. Use el cuerpo crudo (bytes), no el JSON re-serializado.
# Firma manual para probar con su secreto (t = ahora en segundos)
T=$(date +%s); BODY='{"id":"evt_test","tipo":"paquete.prueba"}'
SIG=$(printf '%s.%s' "$T" "$BODY" | openssl dgst -sha256 -hmac "$VALIDA_WEBHOOK_SECRET" | awk '{print $2}')
curl -s -X POST https://suempresa.co/valida/webhook \
-H "Content-Type: application/json" -H "X-Valida-Event: paquete.prueba" \
-H "X-Valida-Signature: t=$T,v1=$SIG" -d "$BODY"11. Concurrencia para lotes
No hay endpoint de lote: un cargue de 9.000 filas son 9.000 llamadas a /validate. Está bien, siempre que las haga con cabeza. Esta es la guía que Valida aguanta hoy y que MeTRIK monitorea:
- Hasta 20 peticiones en vuelo por cliente API. Más no es más rápido: entran a la misma base de datos y se estorban.
- Una Idempotency-Key por fila (por ejemplo
{lote}-{fila}o un UUID guardado con la fila). Reintente solo con esa clave. - Timeout 60 s por petición y reintento exponencial (2 s, 4 s, 8 s) ante timeout, error de red y
500. - Pare el lote si recibe
401o402: ninguna fila siguiente va a pasar. - Guarde por fila
consulta_id,severidadylistas_consultadas. Con losconsulta_idpuede pedir un solo PDF agregado enPOST /reporte-lote(hasta 500 por PDF). - Horario: las listas se actualizan a las 05:15 de Bogotá; en esa ventana una consulta puede tardar un poco más. Si puede elegir, corra los lotes grandes fuera de esa hora.
# 20 en paralelo con GNU parallel; cada linea del CSV: referencia,tipo,nombre,doc_tipo,doc_numero
parallel -j 20 --colsep ',' \
'curl -s -X POST https://api.valida.metrikone.co/api/v1/validate \
-H "Authorization: Bearer $VALIDA_API_KEY" -H "Content-Type: application/json" \
-H "Idempotency-Key: lote-2026-09-08-{1}" \
-d "{\"tipo\":\"{2}\",\"nombre\":\"{3}\",\"documento\":{\"tipo\":\"{4}\",\"numero\":\"{5}\"},\"referencia_externa\":\"{1}\"}" \
> resultados/{1}.json' :::: filas.csv12. Formato de error y códigos
Toda respuesta de error, en cualquier ruta /api/v1/*, tiene la misma forma:
{
"error": "validation_error", // codigo estable: programe contra este
"message": "El cuerpo de la peticion no cumple el esquema. Revise el campo issues.",
"doc_url": "https://app.valida.metrikone.co/docs#error-validation_error",
"request_id": "req_3f9c1a2b4d5e6f708192a3b4", // mismo valor del header X-Valida-Request-Id
"issues": [ { "path": ["nombre"], "message": "..." } ] // solo en validation_error
}| HTTP | error | Cuándo | Qué hacer |
|---|---|---|---|
| 400 | invalid_json | El cuerpo no es JSON válido. | Corrija el cuerpo. No reintente igual. |
| 400 | validation_error | El JSON no cumple el esquema (falta tipo, ni nombre ni documento, NIT inválido…). | Lea issues[] (path + message) y corrija ese campo. |
| 400 | sujeto_obligado_requerido | Su cliente opera para terceros y la consulta no trae sujeto_obligado. | Agregue { razon_social, nit } del sujeto obligado final. |
| 400 | idempotency_key_invalida | Idempotency-Key vacía, con espacios o de más de 64 caracteres. | Use un UUID v4. |
| 400 | consulta_ids_requeridos | POST /reporte-lote sin consulta_ids. | Envíe al menos un consulta_id. |
| 400 | maximo_500_consultas_por_lote | Más de 500 consulta_ids en un PDF. | Parta el lote. |
| 401 | invalid_api_key | Key ausente, mal formada, revocada o de cliente inactivo. | Revise el header Authorization. Si se rotó, use la nueva. Pare el lote. |
| 402 | paquete_vencido_sin_pago | Cuenta de cobro vencida sin pago registrado Y consumo por encima del 100%. | Avise a cartera y registre el pago con soporte. No reintente en bucle; el 402 no cambia solo. |
| 404 | not_found | La consulta no existe o no es de su cliente. | Verifique el consulta_id. |
| 404 | consultas_no_encontradas_para_cliente | Ninguno de los consulta_ids del lote es suyo. | Verifique los ids. |
| 409 | idempotency_error | La Idempotency-Key ya se usó con un cuerpo distinto. | Use una clave nueva para una consulta distinta. |
| 409 | sin_plan_asignado | GET /cuenta/consumo de un cliente sin paquete. | Escriba a soporte para activarlo. /validate sigue funcionando. |
| 500 | persistencia_error | La consulta corrió pero no se pudo guardar. No se cobró. | Reintente con la misma Idempotency-Key tras 2 s. |
| 500 | db_error | Error interno al leer o escribir. | Reintente con espera exponencial. Si persiste, soporte con el request_id. |
Lo que NO existe
No hay 429, Retry-After, 403 permiso_denegado ni 503. Si su cliente HTTP los maneja de forma genérica, bien; pero no programe lógica de negocio sobre ellos.
13. Endpoints con ejemplos
| Método | Ruta | Para qué |
|---|---|---|
| GET | /api/v1/health | Estado del servicio (sin auth). |
| POST | /api/v1/validate | Validar una persona o entidad contra las listas SARLAFT. |
| POST | /api/v1/diligencia | Antecedentes nacionales de referencia. Módulo aparte, ver §6. |
| GET | /api/v1/consultas | Listar y filtrar sus consultas. |
| GET | /api/v1/reporte/{consulta_id} | PDF auditable de una consulta. |
| POST | /api/v1/reporte-lote | PDF agregado de hasta 500 consultas. |
| GET | /api/v1/cuenta/consumo | Contador del paquete y estado de cobro. |
| GET | /api/v1/cuenta/consumo/historial | Periodos anteriores. |
| GET / PUT | /api/v1/cuenta/alertas | Ver y configurar alertas. |
| POST | /api/v1/cuenta/alertas/webhook/rotar-secreto | Rotar el secreto del webhook. |
| POST | /api/v1/cuenta/alertas/prueba | Probar los canales. |
Las rutas /api/v1/kyc/* y /api/v1/compliance/dual/* son internas de MeTRIK ONE y no forman parte del contrato con integradores. Las /api/admin/* son de operación de MeTRIK.
POST /api/v1/validate
curl -s -X POST https://api.valida.metrikone.co/api/v1/validate \
-H "Authorization: Bearer $VALIDA_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 4c6d1a4e-0e0f-4c37-9c7d-6a5b6f1f2e3d" \
-d '{
"tipo": "natural",
"nombre": "Juan Perez Gomez",
"documento": { "tipo": "CC", "numero": "1077089147" },
"fecha_nacimiento": "1985-03-15",
"pais": "CO",
"referencia_externa": "EXP-2026-00123",
"sujeto_obligado": { "razon_social": "Transportes La Sabana SAS", "nit": "800123456" }
}' -D -{
"consulta_id": "4f8e2a91-1c3e-4f0a-9d2b-1a2b3c4d5e6f",
"severidad": "sin_hallazgo",
"total_matches": 0,
"consulta_parcial": false,
"matches": [],
"hash_reporte": "a3f8d92e4b1c...",
"consultado": { "tipo": "natural", "nombre": "Juan Perez Gomez", "documento": { "tipo": "CC", "numero": "1077089147" } },
"sujeto_obligado": { "razon_social": "Transportes La Sabana SAS", "nit": "800123456" },
"referencia_externa": "EXP-2026-00123",
"listas_consultadas": [
{ "slug": "onu_consolidated", "nombre": "ONU Consolidated Sanctions List", "tier": "1_vinculante",
"version_id": "…", "hash_contenido": "…", "fetched_en": "2026-09-05T05:15:12Z", "total_entradas": 1002 },
...
],
"fecha_reporte": "2026-09-08T14:32:00.512Z",
"cliente": "Plataforma Ejemplo"
}{
"lista": "ofac_sdn",
"lista_nombre": "OFAC Specially Designated Nationals (SDN)",
"tier": "3_referencia",
"vinculante_colombia": false,
"nombre_coincidencia": "PEREZ GOMEZ, Juan",
"score": 0.97,
"resultado": "exacto",
"fundamento_legal": "SDNTK",
"match_por": "nombre",
"documento_coincidencia": { "tipo": "Cedula No.", "numero": "1077089147", "pais": "Colombia" },
"derivado": false,
"derivado_de": null
}GET /api/v1/consultas
curl -s "https://api.valida.metrikone.co/api/v1/consultas?limite=50&desde=2026-09-01T00:00:00Z&severidad=alto&sujeto_obligado_nit=800123456" \
-H "Authorization: Bearer $VALIDA_API_KEY"GET /api/v1/reporte/{consulta_id}
curl -s https://api.valida.metrikone.co/api/v1/reporte/4f8e2a91-1c3e-4f0a-9d2b-1a2b3c4d5e6f \
-H "Authorization: Bearer $VALIDA_API_KEY" -o reporte.pdfPOST /api/v1/reporte-lote
curl -s -X POST https://api.valida.metrikone.co/api/v1/reporte-lote \
-H "Authorization: Bearer $VALIDA_API_KEY" -H "Content-Type: application/json" \
-d '{ "consulta_ids": ["4f8e2a91-…", "7b2c1d83-…"], "titulo": "Cargue plantilla septiembre 2026" }' -o lote.pdfGET /api/v1/cuenta/consumo
curl -s https://api.valida.metrikone.co/api/v1/cuenta/consumo -H "Authorization: Bearer $VALIDA_API_KEY"{
"cliente": { "cliente_id": "55a4400c-…", "nombre": "Plataforma Ejemplo" },
"plan": { "codigo": "20K", "nombre": "Paquete 20.000 consultas/mes", "consultas_incluidas": 20000, "precio_mes": 1400000,
"precio_unitario": 70, "precio_excedente": 50, "a_medida": false, "moneda": "COP", "iva_incluido": false },
"periodo": { "inicio": "2026-09-01", "fin": "2026-10-01", "zona": "America/Bogota", "dias_restantes": 23, "dia_del_periodo": 8,
"renovacion_en": "2026-10-01T00:00:00-05:00" },
"consumo": { "consumidas": 16420, "incluidas": 20000, "restantes": 3580, "porcentaje": 82.1, "excedente": 0,
"excedente_precio_unitario": 50, "excedente_valor_estimado": 0, "estado": "umbral_80", "actualizado_en": "2026-09-08T14:02:11Z" },
"cobro": { "cuenta_emitida_en": "2026-09-07T16:10:00Z", "cuenta_vence_en": "2026-09-22T00:00:00Z", "cuenta_referencia": "CC-0042",
"pago_registrado_en": null, "cuenta_vencida_sin_pago": false, "bloqueado": false },
"politica": { "bloqueo_por_consumo": false, "bloqueo_por_mora": "Solo con cuenta de cobro vencida sin pago registrado Y consumo por encima del 100% del paquete.",
"excedente": "Se cobra al precio unitario del escalon siguiente y entra en la cuenta del siguiente periodo.",
"rollover": false, "ciclo": "Mes calendario America/Bogota", "umbrales_alerta": [80, 100] }
}GET /api/v1/cuenta/consumo/historial
curl -s "https://api.valida.metrikone.co/api/v1/cuenta/consumo/historial?periodos=6" -H "Authorization: Bearer $VALIDA_API_KEY"GET / PUT /api/v1/cuenta/alertas
curl -s https://api.valida.metrikone.co/api/v1/cuenta/alertas -H "Authorization: Bearer $VALIDA_API_KEY"
curl -s -X PUT https://api.valida.metrikone.co/api/v1/cuenta/alertas \
-H "Authorization: Bearer $VALIDA_API_KEY" -H "Content-Type: application/json" \
-d '{ "umbrales": [50, 80, 100, 120], "emails": ["cumplimiento@suempresa.co"], "webhook": { "url": "https://suempresa.co/valida/webhook" }, "activa": true }'POST /api/v1/cuenta/alertas/webhook/rotar-secreto · POST /api/v1/cuenta/alertas/prueba
curl -s -X POST https://api.valida.metrikone.co/api/v1/cuenta/alertas/webhook/rotar-secreto -H "Authorization: Bearer $VALIDA_API_KEY"
curl -s -X POST https://api.valida.metrikone.co/api/v1/cuenta/alertas/prueba -H "Authorization: Bearer $VALIDA_API_KEY"14. Glosario
| Término | Significado |
|---|---|
| tier | Clasificación normativa de la lista: 1_vinculante (obligación legal en Colombia), 2_obligatoria (el sujeto obligado debe construirla: PEP), 3_referencia (no vinculante, estándar de facto: OFAC SDN, Unión Europea y US State Dept FTO). |
| match | Una entrada de una lista cuyo nombre, alias o documento coincide con lo consultado. Una consulta puede tener cero, uno o varios. |
| score | Similitud entre 0 y 1 del nombre consultado contra el nombre o alias de la entrada (Jaro-Winkler 70% + Levenshtein 30% sobre nombres normalizados). Un match por documento tiene score 1. |
| resultado | exacto (score ≥ 0.95) o posible (0.70 a 0.95). Un posible exige análisis del oficial de cumplimiento; no es una confirmación. |
| severidad | Resumen de la consulta: alto (exacto en tier 1), medio (exacto en tier 2 o 3), bajo (solo posibles), informativo, sin_hallazgo. |
| consulta_parcial | La consulta trajo solo nombre o solo documento. La cobertura puede ser menor; el PDF lo advierte. |
| match_por / derivado | Por qué campo coincidió (nombre o documento). derivado = salió de un segundo pase con el dato complementario que trajo la entrada (por ejemplo, un documento encontrado por nombre se revalidó contra las demás listas). |
| versión de lista | Descarga concreta de una lista desde su fuente oficial, identificada por version_id, hash_contenido y fetched_en. Toda consulta registra las versiones contra las que corrió. |
| sujeto obligado | La empresa que por ley debe hacer la verificación SARLAFT. Con un agregador, es el cliente final de la plataforma, no la plataforma. |
| periodo | Mes calendario en America/Bogotá. El contador vuelve a cero el día 1. |
| paquete / incluidas | Consultas del mes cubiertas por el precio fijo del plan. |
| excedente | Consultas por encima de las incluidas. Se cobran al unitario del escalón siguiente en la cuenta del siguiente periodo. No bloquean. |
| bloqueo por mora | Único caso en que /validate responde 402: cuenta de cobro vencida sin pago registrado y consumo por encima del 100%. |
| Idempotency-Key | Clave que usted elige por consulta para que un reintento devuelva la misma respuesta en vez de crear (y cobrar) otra. |
| request_id | Identificador de cada petición (header X-Valida-Request-Id y cuerpo de error). Cítelo en soporte. |
15. Changelog
1.2.0 · 2026-09-09
- Nuevo módulo
POST /diligencia(beta) con dos fuentes nacionales: SIRI de la Procuraduría y multas de SECOP II. Aislado del motor SARLAFT: tabla propia, sello de referencia y consumo aparte. Ver §6. - El catálogo de listas queda separado por módulo.
/validateylistas_consultadas[]solo devuelven listas SARLAFT; ninguna fuente de Diligencia puede entrar a un reporte SARLAFT.
1.1.0 · 2026-09-08
- Formato de error uniforme
{ error, message, doc_url, request_id, issues? }y headerX-Valida-Request-Iden toda respuesta. CORS (preflight) en/api/v1. Idempotency-KeyenPOST /validatecon replay 24 h y409 idempotency_error. Camporeferencia_externay filtro en/consultas.listas_consultadas[]yX-Valida-Listas-Version: la versión de cada lista queda grabada con la consulta y el PDF la lee de ahí.sujeto_obligadoen/validate(obligatorio para clientes que operan para terceros), estampado en el PDF; filtrosujeto_obligado_nit.- Contador de paquete: headers
X-Valida-Plan/X-Valida-Periodo-*/X-Valida-Consumo-*,GET /cuenta/consumoy/cuenta/consumo/historial. - Cobro y bloqueo por mora:
402 paquete_vencido_sin_pagosolo con cuenta vencida sin pago y consumo > 100%. - Alertas:
GET/PUT /cuenta/alertas, rotación de secreto, prueba, webhooks firmados (X-Valida-Signature) con reintentos, eventospaquete.*. - Retención de consultas y evidencia: 10 años (antes 5).
- Documentación: se retiran del contrato el
429 rate_limit,403 permiso_denegadoy503que nunca existieron, y el límite de "1000 consultas/día".
1.0.0-mvp · 2026-05
POST /validate,GET /consultas,GET /reporte/{id},POST /reporte-lote,GET /health.
Política de versionado: los cambios compatibles (campos y headers nuevos, códigos de error nuevos) se publican aquí sin cambiar la ruta. Un cambio incompatible saldría como /api/v2 con al menos 90 días de convivencia.
16. Soporte
- Email: mauricio.moreno@metrik.com.co
- WhatsApp: +57 315 950 9103
- Qué incluir: el
request_id, la hora (UTC), la ruta y el códigoerror. Con eso se ubica la petición en segundos. - Emisión y rotación de keys, activación de paquete, registro de pagos: por los mismos canales.
- Horarios, categorías y tiempos de respuesta: Política de Atención y Soporte y ANS.