{"info":{"name":"VerifyCol · API del canal B2B","description":"Colección generada desde la documentación viva del canal, así que no puede quedar desactualizada respecto de ella.\n\nCÓMO EMPEZAR\n1. Editá las variables de la colección. Hay DOS para la key, y no son intercambiables:\n   · `api_key_test` — tu key de PRUEBA (`vf_test_…`). La usa SÓLO la carpeta `0 · Sandbox`, que no sale si esta variable no empieza con `vf_test_`.\n   · `api_key` — la que usan todas las demás carpetas. Con una key de prueba (`vf_test_…`) todo corre contra el sandbox: gratis, con datos sintéticos y sin tocar a nadie. Con una key live (`vf_live_…`) cada consulta va a los portales reales, se cobra, y el documento tiene que ser el de un titular que te autorizó: los de esta colección son del banco del sandbox (900000001…), sintéticos en el sandbox: no los uses con una key live.\n   · `webhook_url` — la URL de TU receptor de webhooks. `7 · Webhooks → Registrar un webhook` no sale con una key live si está vacía.\n2. Empezá por `0 · Sandbox`, o probá `1 · Reporte unificado → Estimar costo`: es gratis y no consulta nada.\n3. Para las consultas por fuente, acordate de que son ASÍNCRONAS: devuelven `task_id` y el resultado se recoge en `3 · Tareas`.\n\nAUTORIZACIÓN DEL TITULAR (Ley 1581) — YA VIENE PUESTA\nToda consulta de datos personales exige declarar que contás con la autorización del titular. Son DOS formas según la llamada, y los requests de esta colección ya las traen:\n· Consulta directa por fuente → header `X-Data-Authorization: true`\n· Reporte unificado → en el CUERPO: `\"data_authorization_declared\": true`\n· `estimate`, el polling de tareas y los catálogos NO la necesitan (no consultan datos de nadie).\nSi falta, la respuesta es 400 y no se cobra. Las API keys de prueba (`vf_test_`) están exentas EN LA CONSULTA DIRECTA por fuente, no en el reporte unificado: desde que una key test puede crear reportes en el sandbox, ese endpoint exige la declaración igual que con una key live.\n\nTECHOS VIGENTES (por defecto; tu key puede tener uno menor)\n· Por API key: 120 requests/min y 2000/día.\n· Por organización, sumando TODAS sus keys: 600 requests/min y 50000/día.\n· El cubo es uno solo: creates, polls y estimates comparten cupo.\nUn 429 cobra 0 y trae `Retry-After` (la cuenta regresiva real) más `retry_after` y `scope` en el cuerpo. Ver `8 · Errores`.","schema":"https://schema.getpostman.com/json/collection/v2.1.0/collection.json"},"variable":[{"key":"base_url","value":"https://api.verifycol.co","type":"string"},{"key":"api_key","value":"","type":"string"},{"key":"api_key_test","value":"","type":"string"},{"key":"report_id","value":"","type":"string"},{"key":"task_id","value":"","type":"string"},{"key":"idempotency_key","value":"","type":"string"},{"key":"consent_id","value":"","type":"string"},{"key":"sbx_report_id","value":"","type":"string"},{"key":"sbx_consent_id","value":"","type":"string"},{"key":"webhook_id","value":"","type":"string"},{"key":"delivery_id","value":"","type":"string"},{"key":"webhook_url","value":"","type":"string"},{"key":"indice","value":"0","type":"string"},{"key":"j","value":"0","type":"string"}],"item":[{"name":"0 · Sandbox (gratis, sin tocar tu saldo)","item":[{"name":"1. Coincidencia FIRME en OFAC (96) y en la Lista ONU (92)","request":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key_test}}","type":"text"},{"key":"Idempotency-Key","value":"{{$guid}}","type":"text","description":"Identifica ESTA solicitud. Un reintento por timeout de red con la misma clave devuelve el reporte original —con el header `Idempotent-Replayed: true`— en vez de crear y cobrar otro. Ventana: 24 h. `{{$guid}}` genera una clave nueva en cada envío, que es lo correcto para una solicitud nueva."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/reports/","host":["{{base_url}}"],"path":["api","v1","gateway","api","reports"]},"description":"Coincidencia FIRME en OFAC (96) y en la Lista ONU (92)\n\n\n\nDOCUMENTO SINTÉTICO: 900000001 (CC). Es sintético en el sandbox; no lo uses con una key live.\n\nTipos de documento aceptados: CC, CE, NIT, PA. OJO: el reporte acepta MENOS tipos que la consulta directa por fuente —que admite hasta CC, CE, NIT, PA, PPT y TI según la fuente—. Un tipo fuera de este conjunto NO omite una fuente: rechaza el reporte entero.\n\nQUÉ TIENE QUE PASAR: el reporte cierra `completed` con `overall_status: danger`.","body":{"mode":"raw","raw":"{\n  \"tipo_documento\": \"CC\",\n  \"numero_documento\": \"900000001\",\n  \"selected_endpoints\": [\n    \"contraloria-natural\",\n    \"procuraduria-ordinario\",\n    \"policia-antecedentes\",\n    \"policia-medidas-correctivas\",\n    \"ofac-search\",\n    \"onu-search\",\n    \"pep-search\",\n    \"uk-ofsi-search\",\n    \"eu-sanctions-search\",\n    \"canada-osfi-search\",\n    \"australia-dfat-search\",\n    \"swiss-seco-search\",\n    \"interpol-search\",\n    \"worldbank-debarred-search\"\n  ],\n  \"data_authorization_declared\": true\n}","options":{"raw":{"language":"json"}}}},"id":"sbx-firme_ofac_onu","event":[{"listen":"test","script":{"type":"text/javascript","exec":["// El sandbox necesita una key de PRUEBA (`vf_test_…`). Con una de","// producción, esto consultaría portales reales con un documento sintético","// y cobraría créditos: sin key de prueba, las afirmaciones quedan en","// `skipped` con una nota en la consola en vez de en rojo — un rojo por un","// ambiente sin preparar entrena al certificador a ignorar los rojos.","var claveDePrueba = pm.variables.replaceIn(\"{{api_key_test}}\") || \"\";","var esPrueba = claveDePrueba.indexOf(\"vf_test_\") === 0;","if (!esPrueba) {","    console.warn(\"Pegá tu API key de PRUEBA (vf_test_...) en la variable de colección `api_key_test`. Este escenario no se evaluó.\");","}","var t = esPrueba ? pm.test : pm.test.skip;","// Sondeo hasta estado terminal. El sandbox cierra sus tareas asíncronas a","// los pocos segundos (enseña la FORMA del polling, no las latencias","// reales: en producción son p50 40 s / p95 2,1 min).","function sondear(id, intentos, cb) {","    pm.sendRequest({","        url: pm.variables.replaceIn(\"{{base_url}}/api/v1/gateway/api/reports/\") + id,","        method: \"GET\",","        header: { \"X-API-KEY\": claveDePrueba }","    }, function (err, res) {","        if (err) { return cb(err, null); }","        var r = res.json();","        var terminal = [\"completed\", \"partial\", \"failed\"].indexOf(r.status) >= 0;","        if (terminal || intentos <= 1) { return cb(null, r); }","        setTimeout(function () { sondear(id, intentos - 1, cb); }, 1500);","    });","}","","t(\"La creación responde 201 y el reporte NACE EN EL SANDBOX\", function () {","    pm.response.to.have.status(201);","    var r = pm.response.json();","    pm.expect(r.environment, \"el reporte no nació en el sandbox\").to.eql(\"test\");","    pm.expect(r.test_mode, \"`test_mode` es el booleano que un receptor filtra\").to.be.true;","    pm.collectionVariables.set(\"sbx_report_id\", r.id);","});","","t(\"El escenario cierra `completed` con veredicto `danger`\", function (done) {","    sondear(pm.response.json().id, 14, function (err, r) {","        pm.expect(err).to.equal(null);","        pm.expect(r.status, \"el escenario `firme_ofac_onu` no cerró como el banco dice\").to.eql(\"completed\");","        pm.expect(r.overall_status, \"el veredicto no es el del banco\").to.eql(\"danger\");","        done();","    });","});"]}}],"response":[{"name":"1. Coincidencia FIRME en OFAC (96) y en la Lista ONU (92) — ejemplo","originalRequest":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key_test}}","type":"text"},{"key":"Idempotency-Key","value":"{{$guid}}","type":"text","description":"Identifica ESTA solicitud. Un reintento por timeout de red con la misma clave devuelve el reporte original —con el header `Idempotent-Replayed: true`— en vez de crear y cobrar otro. Ventana: 24 h. `{{$guid}}` genera una clave nueva en cada envío, que es lo correcto para una solicitud nueva."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/reports/","host":["{{base_url}}"],"path":["api","v1","gateway","api","reports"]},"description":"Coincidencia FIRME en OFAC (96) y en la Lista ONU (92)\n\n\n\nDOCUMENTO SINTÉTICO: 900000001 (CC). Es sintético en el sandbox; no lo uses con una key live.\n\nTipos de documento aceptados: CC, CE, NIT, PA. OJO: el reporte acepta MENOS tipos que la consulta directa por fuente —que admite hasta CC, CE, NIT, PA, PPT y TI según la fuente—. Un tipo fuera de este conjunto NO omite una fuente: rechaza el reporte entero.\n\nQUÉ TIENE QUE PASAR: el reporte cierra `completed` con `overall_status: danger`.","body":{"mode":"raw","raw":"{\n  \"tipo_documento\": \"CC\",\n  \"numero_documento\": \"900000001\",\n  \"selected_endpoints\": [\n    \"contraloria-natural\",\n    \"procuraduria-ordinario\",\n    \"policia-antecedentes\",\n    \"policia-medidas-correctivas\",\n    \"ofac-search\",\n    \"onu-search\",\n    \"pep-search\",\n    \"uk-ofsi-search\",\n    \"eu-sanctions-search\",\n    \"canada-osfi-search\",\n    \"australia-dfat-search\",\n    \"swiss-seco-search\",\n    \"interpol-search\",\n    \"worldbank-debarred-search\"\n  ],\n  \"data_authorization_declared\": true\n}","options":{"raw":{"language":"json"}}}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": \"3f2a8c10-5b7e-4d21-9a44-1c8e6b0d5f93\",\n  \"status\": \"processing\",\n  \"overall_status\": null,\n  \"subject_document_type\": \"CC\",\n  \"subject_document_number\": \"900000001\",\n  \"subject_full_name\": null,\n  \"total_sources\": 14,\n  \"completed_sources\": 0,\n  \"successful_sources\": 0,\n  \"failed_sources\": 0,\n  \"sources\": [],\n  \"total_credits_charged\": 14,\n  \"credits_reserved\": 14,\n  \"credits_refunded\": 0,\n  \"omitted_sources\": [],\n  \"omitted_sources_count\": 0,\n  \"has_pdf\": false,\n  \"pdf_generated_at\": null,\n  \"created_at\": \"2026-09-02T14:05:11Z\",\n  \"completed_at\": null,\n  \"deduplicated\": false,\n  \"origin\": null,\n  \"environment\": \"test\",\n  \"test_mode\": true,\n  \"external_reference\": null,\n  \"correlation_id\": null,\n  \"informational_only\": false,\n  \"informational_sources\": 0,\n  \"conclusive_sources\": 0,\n  \"coverage_sufficient\": false,\n  \"covered_dimensions\": [],\n  \"uncovered_dimensions\": [],\n  \"uncovered_coverage_groups\": [],\n  \"narrative_status\": \"none\",\n  \"risk_analysis\": null,\n  \"risk_narrative\": null,\n  \"narrative_generated_at\": null\n}"}]},{"name":"2. PEP en banda de revisión (possible_match, score 81)","request":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key_test}}","type":"text"},{"key":"Idempotency-Key","value":"{{$guid}}","type":"text","description":"Identifica ESTA solicitud. Un reintento por timeout de red con la misma clave devuelve el reporte original —con el header `Idempotent-Replayed: true`— en vez de crear y cobrar otro. Ventana: 24 h. `{{$guid}}` genera una clave nueva en cada envío, que es lo correcto para una solicitud nueva."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/reports/","host":["{{base_url}}"],"path":["api","v1","gateway","api","reports"]},"description":"PEP en banda de revisión (possible_match, score 81)\n\n\n\nDOCUMENTO SINTÉTICO: 900000002 (CC). Es sintético en el sandbox; no lo uses con una key live.\n\nTipos de documento aceptados: CC, CE, NIT, PA. OJO: el reporte acepta MENOS tipos que la consulta directa por fuente —que admite hasta CC, CE, NIT, PA, PPT y TI según la fuente—. Un tipo fuera de este conjunto NO omite una fuente: rechaza el reporte entero.\n\nQUÉ TIENE QUE PASAR: el reporte cierra `completed` con `overall_status: warning`.","body":{"mode":"raw","raw":"{\n  \"tipo_documento\": \"CC\",\n  \"numero_documento\": \"900000002\",\n  \"selected_endpoints\": [\n    \"contraloria-natural\",\n    \"procuraduria-ordinario\",\n    \"policia-antecedentes\",\n    \"policia-medidas-correctivas\",\n    \"ofac-search\",\n    \"onu-search\",\n    \"pep-search\",\n    \"uk-ofsi-search\",\n    \"eu-sanctions-search\",\n    \"canada-osfi-search\",\n    \"australia-dfat-search\",\n    \"swiss-seco-search\",\n    \"interpol-search\",\n    \"worldbank-debarred-search\"\n  ],\n  \"data_authorization_declared\": true\n}","options":{"raw":{"language":"json"}}}},"id":"sbx-pep_en_revision","event":[{"listen":"test","script":{"type":"text/javascript","exec":["// El sandbox necesita una key de PRUEBA (`vf_test_…`). Con una de","// producción, esto consultaría portales reales con un documento sintético","// y cobraría créditos: sin key de prueba, las afirmaciones quedan en","// `skipped` con una nota en la consola en vez de en rojo — un rojo por un","// ambiente sin preparar entrena al certificador a ignorar los rojos.","var claveDePrueba = pm.variables.replaceIn(\"{{api_key_test}}\") || \"\";","var esPrueba = claveDePrueba.indexOf(\"vf_test_\") === 0;","if (!esPrueba) {","    console.warn(\"Pegá tu API key de PRUEBA (vf_test_...) en la variable de colección `api_key_test`. Este escenario no se evaluó.\");","}","var t = esPrueba ? pm.test : pm.test.skip;","// Sondeo hasta estado terminal. El sandbox cierra sus tareas asíncronas a","// los pocos segundos (enseña la FORMA del polling, no las latencias","// reales: en producción son p50 40 s / p95 2,1 min).","function sondear(id, intentos, cb) {","    pm.sendRequest({","        url: pm.variables.replaceIn(\"{{base_url}}/api/v1/gateway/api/reports/\") + id,","        method: \"GET\",","        header: { \"X-API-KEY\": claveDePrueba }","    }, function (err, res) {","        if (err) { return cb(err, null); }","        var r = res.json();","        var terminal = [\"completed\", \"partial\", \"failed\"].indexOf(r.status) >= 0;","        if (terminal || intentos <= 1) { return cb(null, r); }","        setTimeout(function () { sondear(id, intentos - 1, cb); }, 1500);","    });","}","","t(\"La creación responde 201 y el reporte NACE EN EL SANDBOX\", function () {","    pm.response.to.have.status(201);","    var r = pm.response.json();","    pm.expect(r.environment, \"el reporte no nació en el sandbox\").to.eql(\"test\");","    pm.expect(r.test_mode, \"`test_mode` es el booleano que un receptor filtra\").to.be.true;","    pm.collectionVariables.set(\"sbx_report_id\", r.id);","});","","t(\"El escenario cierra `completed` con veredicto `warning`\", function (done) {","    sondear(pm.response.json().id, 14, function (err, r) {","        pm.expect(err).to.equal(null);","        pm.expect(r.status, \"el escenario `pep_en_revision` no cerró como el banco dice\").to.eql(\"completed\");","        pm.expect(r.overall_status, \"el veredicto no es el del banco\").to.eql(\"warning\");","        done();","    });","});"]}}],"response":[{"name":"2. PEP en banda de revisión (possible_match, score 81) — ejemplo","originalRequest":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key_test}}","type":"text"},{"key":"Idempotency-Key","value":"{{$guid}}","type":"text","description":"Identifica ESTA solicitud. Un reintento por timeout de red con la misma clave devuelve el reporte original —con el header `Idempotent-Replayed: true`— en vez de crear y cobrar otro. Ventana: 24 h. `{{$guid}}` genera una clave nueva en cada envío, que es lo correcto para una solicitud nueva."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/reports/","host":["{{base_url}}"],"path":["api","v1","gateway","api","reports"]},"description":"PEP en banda de revisión (possible_match, score 81)\n\n\n\nDOCUMENTO SINTÉTICO: 900000002 (CC). Es sintético en el sandbox; no lo uses con una key live.\n\nTipos de documento aceptados: CC, CE, NIT, PA. OJO: el reporte acepta MENOS tipos que la consulta directa por fuente —que admite hasta CC, CE, NIT, PA, PPT y TI según la fuente—. Un tipo fuera de este conjunto NO omite una fuente: rechaza el reporte entero.\n\nQUÉ TIENE QUE PASAR: el reporte cierra `completed` con `overall_status: warning`.","body":{"mode":"raw","raw":"{\n  \"tipo_documento\": \"CC\",\n  \"numero_documento\": \"900000002\",\n  \"selected_endpoints\": [\n    \"contraloria-natural\",\n    \"procuraduria-ordinario\",\n    \"policia-antecedentes\",\n    \"policia-medidas-correctivas\",\n    \"ofac-search\",\n    \"onu-search\",\n    \"pep-search\",\n    \"uk-ofsi-search\",\n    \"eu-sanctions-search\",\n    \"canada-osfi-search\",\n    \"australia-dfat-search\",\n    \"swiss-seco-search\",\n    \"interpol-search\",\n    \"worldbank-debarred-search\"\n  ],\n  \"data_authorization_declared\": true\n}","options":{"raw":{"language":"json"}}}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": \"3f2a8c10-5b7e-4d21-9a44-1c8e6b0d5f93\",\n  \"status\": \"processing\",\n  \"overall_status\": null,\n  \"subject_document_type\": \"CC\",\n  \"subject_document_number\": \"900000002\",\n  \"subject_full_name\": null,\n  \"total_sources\": 14,\n  \"completed_sources\": 0,\n  \"successful_sources\": 0,\n  \"failed_sources\": 0,\n  \"sources\": [],\n  \"total_credits_charged\": 14,\n  \"credits_reserved\": 14,\n  \"credits_refunded\": 0,\n  \"omitted_sources\": [],\n  \"omitted_sources_count\": 0,\n  \"has_pdf\": false,\n  \"pdf_generated_at\": null,\n  \"created_at\": \"2026-09-02T14:05:11Z\",\n  \"completed_at\": null,\n  \"deduplicated\": false,\n  \"origin\": null,\n  \"environment\": \"test\",\n  \"test_mode\": true,\n  \"external_reference\": null,\n  \"correlation_id\": null,\n  \"informational_only\": false,\n  \"informational_sources\": 0,\n  \"conclusive_sources\": 0,\n  \"coverage_sufficient\": false,\n  \"covered_dimensions\": [],\n  \"uncovered_dimensions\": [],\n  \"uncovered_coverage_groups\": [],\n  \"narrative_status\": \"none\",\n  \"risk_analysis\": null,\n  \"risk_narrative\": null,\n  \"narrative_generated_at\": null\n}"}]},{"name":"3. Sujeto limpio en las 14 fuentes, con ADRES y RUNT informativas","request":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key_test}}","type":"text"},{"key":"Idempotency-Key","value":"{{$guid}}","type":"text","description":"Identifica ESTA solicitud. Un reintento por timeout de red con la misma clave devuelve el reporte original —con el header `Idempotent-Replayed: true`— en vez de crear y cobrar otro. Ventana: 24 h. `{{$guid}}` genera una clave nueva en cada envío, que es lo correcto para una solicitud nueva."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/reports/","host":["{{base_url}}"],"path":["api","v1","gateway","api","reports"]},"description":"Sujeto limpio en las 14 fuentes, con ADRES y RUNT informativas\n\n\n\nDOCUMENTO SINTÉTICO: 900000003 (CC). Es sintético en el sandbox; no lo uses con una key live.\n\nTipos de documento aceptados: CC, CE, NIT, PA. OJO: el reporte acepta MENOS tipos que la consulta directa por fuente —que admite hasta CC, CE, NIT, PA, PPT y TI según la fuente—. Un tipo fuera de este conjunto NO omite una fuente: rechaza el reporte entero.\n\nQUÉ TIENE QUE PASAR: el reporte cierra `completed` con `overall_status: clean`.","body":{"mode":"raw","raw":"{\n  \"tipo_documento\": \"CC\",\n  \"numero_documento\": \"900000003\",\n  \"selected_endpoints\": [\n    \"contraloria-natural\",\n    \"procuraduria-ordinario\",\n    \"policia-antecedentes\",\n    \"policia-medidas-correctivas\",\n    \"ofac-search\",\n    \"onu-search\",\n    \"pep-search\",\n    \"uk-ofsi-search\",\n    \"eu-sanctions-search\",\n    \"canada-osfi-search\",\n    \"australia-dfat-search\",\n    \"swiss-seco-search\",\n    \"interpol-search\",\n    \"worldbank-debarred-search\",\n    \"adres-afiliados-compensados\",\n    \"runt-persona-consultar\"\n  ],\n  \"data_authorization_declared\": true\n}","options":{"raw":{"language":"json"}}}},"id":"sbx-limpio","event":[{"listen":"test","script":{"type":"text/javascript","exec":["// El sandbox necesita una key de PRUEBA (`vf_test_…`). Con una de","// producción, esto consultaría portales reales con un documento sintético","// y cobraría créditos: sin key de prueba, las afirmaciones quedan en","// `skipped` con una nota en la consola en vez de en rojo — un rojo por un","// ambiente sin preparar entrena al certificador a ignorar los rojos.","var claveDePrueba = pm.variables.replaceIn(\"{{api_key_test}}\") || \"\";","var esPrueba = claveDePrueba.indexOf(\"vf_test_\") === 0;","if (!esPrueba) {","    console.warn(\"Pegá tu API key de PRUEBA (vf_test_...) en la variable de colección `api_key_test`. Este escenario no se evaluó.\");","}","var t = esPrueba ? pm.test : pm.test.skip;","// Sondeo hasta estado terminal. El sandbox cierra sus tareas asíncronas a","// los pocos segundos (enseña la FORMA del polling, no las latencias","// reales: en producción son p50 40 s / p95 2,1 min).","function sondear(id, intentos, cb) {","    pm.sendRequest({","        url: pm.variables.replaceIn(\"{{base_url}}/api/v1/gateway/api/reports/\") + id,","        method: \"GET\",","        header: { \"X-API-KEY\": claveDePrueba }","    }, function (err, res) {","        if (err) { return cb(err, null); }","        var r = res.json();","        var terminal = [\"completed\", \"partial\", \"failed\"].indexOf(r.status) >= 0;","        if (terminal || intentos <= 1) { return cb(null, r); }","        setTimeout(function () { sondear(id, intentos - 1, cb); }, 1500);","    });","}","","t(\"La creación responde 201 y el reporte NACE EN EL SANDBOX\", function () {","    pm.response.to.have.status(201);","    var r = pm.response.json();","    pm.expect(r.environment, \"el reporte no nació en el sandbox\").to.eql(\"test\");","    pm.expect(r.test_mode, \"`test_mode` es el booleano que un receptor filtra\").to.be.true;","    pm.collectionVariables.set(\"sbx_report_id\", r.id);","});","","t(\"El escenario cierra `completed` con veredicto `clean`\", function (done) {","    sondear(pm.response.json().id, 14, function (err, r) {","        pm.expect(err).to.equal(null);","        pm.expect(r.status, \"el escenario `limpio` no cerró como el banco dice\").to.eql(\"completed\");","        pm.expect(r.overall_status, \"el veredicto no es el del banco\").to.eql(\"clean\");","        done();","    });","});"]}}],"response":[{"name":"3. Sujeto limpio en las 14 fuentes, con ADRES y RUNT informativas — ejemplo","originalRequest":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key_test}}","type":"text"},{"key":"Idempotency-Key","value":"{{$guid}}","type":"text","description":"Identifica ESTA solicitud. Un reintento por timeout de red con la misma clave devuelve el reporte original —con el header `Idempotent-Replayed: true`— en vez de crear y cobrar otro. Ventana: 24 h. `{{$guid}}` genera una clave nueva en cada envío, que es lo correcto para una solicitud nueva."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/reports/","host":["{{base_url}}"],"path":["api","v1","gateway","api","reports"]},"description":"Sujeto limpio en las 14 fuentes, con ADRES y RUNT informativas\n\n\n\nDOCUMENTO SINTÉTICO: 900000003 (CC). Es sintético en el sandbox; no lo uses con una key live.\n\nTipos de documento aceptados: CC, CE, NIT, PA. OJO: el reporte acepta MENOS tipos que la consulta directa por fuente —que admite hasta CC, CE, NIT, PA, PPT y TI según la fuente—. Un tipo fuera de este conjunto NO omite una fuente: rechaza el reporte entero.\n\nQUÉ TIENE QUE PASAR: el reporte cierra `completed` con `overall_status: clean`.","body":{"mode":"raw","raw":"{\n  \"tipo_documento\": \"CC\",\n  \"numero_documento\": \"900000003\",\n  \"selected_endpoints\": [\n    \"contraloria-natural\",\n    \"procuraduria-ordinario\",\n    \"policia-antecedentes\",\n    \"policia-medidas-correctivas\",\n    \"ofac-search\",\n    \"onu-search\",\n    \"pep-search\",\n    \"uk-ofsi-search\",\n    \"eu-sanctions-search\",\n    \"canada-osfi-search\",\n    \"australia-dfat-search\",\n    \"swiss-seco-search\",\n    \"interpol-search\",\n    \"worldbank-debarred-search\",\n    \"adres-afiliados-compensados\",\n    \"runt-persona-consultar\"\n  ],\n  \"data_authorization_declared\": true\n}","options":{"raw":{"language":"json"}}}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": \"3f2a8c10-5b7e-4d21-9a44-1c8e6b0d5f93\",\n  \"status\": \"processing\",\n  \"overall_status\": null,\n  \"subject_document_type\": \"CC\",\n  \"subject_document_number\": \"900000003\",\n  \"subject_full_name\": null,\n  \"total_sources\": 16,\n  \"completed_sources\": 0,\n  \"successful_sources\": 0,\n  \"failed_sources\": 0,\n  \"sources\": [],\n  \"total_credits_charged\": 16,\n  \"credits_reserved\": 16,\n  \"credits_refunded\": 0,\n  \"omitted_sources\": [],\n  \"omitted_sources_count\": 0,\n  \"has_pdf\": false,\n  \"pdf_generated_at\": null,\n  \"created_at\": \"2026-09-02T14:05:11Z\",\n  \"completed_at\": null,\n  \"deduplicated\": false,\n  \"origin\": null,\n  \"environment\": \"test\",\n  \"test_mode\": true,\n  \"external_reference\": null,\n  \"correlation_id\": null,\n  \"informational_only\": false,\n  \"informational_sources\": 0,\n  \"conclusive_sources\": 0,\n  \"coverage_sufficient\": false,\n  \"covered_dimensions\": [],\n  \"uncovered_dimensions\": [],\n  \"uncovered_coverage_groups\": [],\n  \"narrative_status\": \"none\",\n  \"risk_analysis\": null,\n  \"risk_narrative\": null,\n  \"narrative_generated_at\": null\n}"}]},{"name":"4. Procuraduría caída (`portal_down`, reintentable)","request":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key_test}}","type":"text"},{"key":"Idempotency-Key","value":"{{$guid}}","type":"text","description":"Identifica ESTA solicitud. Un reintento por timeout de red con la misma clave devuelve el reporte original —con el header `Idempotent-Replayed: true`— en vez de crear y cobrar otro. Ventana: 24 h. `{{$guid}}` genera una clave nueva en cada envío, que es lo correcto para una solicitud nueva."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/reports/","host":["{{base_url}}"],"path":["api","v1","gateway","api","reports"]},"description":"Procuraduría caída (`portal_down`, reintentable)\n\n\n\nDOCUMENTO SINTÉTICO: 900000004 (CC). Es sintético en el sandbox; no lo uses con una key live.\n\nTipos de documento aceptados: CC, CE, NIT, PA. OJO: el reporte acepta MENOS tipos que la consulta directa por fuente —que admite hasta CC, CE, NIT, PA, PPT y TI según la fuente—. Un tipo fuera de este conjunto NO omite una fuente: rechaza el reporte entero.\n\nQUÉ TIENE QUE PASAR: el reporte cierra `partial` con `overall_status: warning`.","body":{"mode":"raw","raw":"{\n  \"tipo_documento\": \"CC\",\n  \"numero_documento\": \"900000004\",\n  \"selected_endpoints\": [\n    \"contraloria-natural\",\n    \"procuraduria-ordinario\",\n    \"policia-antecedentes\",\n    \"policia-medidas-correctivas\",\n    \"ofac-search\",\n    \"onu-search\",\n    \"pep-search\",\n    \"uk-ofsi-search\",\n    \"eu-sanctions-search\",\n    \"canada-osfi-search\",\n    \"australia-dfat-search\",\n    \"swiss-seco-search\",\n    \"interpol-search\",\n    \"worldbank-debarred-search\"\n  ],\n  \"data_authorization_declared\": true\n}","options":{"raw":{"language":"json"}}}},"id":"sbx-procuraduria_caida","event":[{"listen":"test","script":{"type":"text/javascript","exec":["// El sandbox necesita una key de PRUEBA (`vf_test_…`). Con una de","// producción, esto consultaría portales reales con un documento sintético","// y cobraría créditos: sin key de prueba, las afirmaciones quedan en","// `skipped` con una nota en la consola en vez de en rojo — un rojo por un","// ambiente sin preparar entrena al certificador a ignorar los rojos.","var claveDePrueba = pm.variables.replaceIn(\"{{api_key_test}}\") || \"\";","var esPrueba = claveDePrueba.indexOf(\"vf_test_\") === 0;","if (!esPrueba) {","    console.warn(\"Pegá tu API key de PRUEBA (vf_test_...) en la variable de colección `api_key_test`. Este escenario no se evaluó.\");","}","var t = esPrueba ? pm.test : pm.test.skip;","// Sondeo hasta estado terminal. El sandbox cierra sus tareas asíncronas a","// los pocos segundos (enseña la FORMA del polling, no las latencias","// reales: en producción son p50 40 s / p95 2,1 min).","function sondear(id, intentos, cb) {","    pm.sendRequest({","        url: pm.variables.replaceIn(\"{{base_url}}/api/v1/gateway/api/reports/\") + id,","        method: \"GET\",","        header: { \"X-API-KEY\": claveDePrueba }","    }, function (err, res) {","        if (err) { return cb(err, null); }","        var r = res.json();","        var terminal = [\"completed\", \"partial\", \"failed\"].indexOf(r.status) >= 0;","        if (terminal || intentos <= 1) { return cb(null, r); }","        setTimeout(function () { sondear(id, intentos - 1, cb); }, 1500);","    });","}","","t(\"La creación responde 201 y el reporte NACE EN EL SANDBOX\", function () {","    pm.response.to.have.status(201);","    var r = pm.response.json();","    pm.expect(r.environment, \"el reporte no nació en el sandbox\").to.eql(\"test\");","    pm.expect(r.test_mode, \"`test_mode` es el booleano que un receptor filtra\").to.be.true;","    pm.collectionVariables.set(\"sbx_report_id\", r.id);","});","","t(\"El escenario cierra `partial` con veredicto `warning`\", function (done) {","    sondear(pm.response.json().id, 14, function (err, r) {","        pm.expect(err).to.equal(null);","        pm.expect(r.status, \"el escenario `procuraduria_caida` no cerró como el banco dice\").to.eql(\"partial\");","        pm.expect(r.overall_status, \"el veredicto no es el del banco\").to.eql(\"warning\");","        var f = r.sources.filter(function (s) { return s.endpoint === \"procuraduria-ordinario\"; })[0];","        pm.expect(f, \"falta la fuente procuraduria-ordinario en la respuesta\").to.not.be.undefined;","        pm.expect(f.error_code, \"el canal no declara por qué falló\").to.eql(\"portal_down\");","        pm.expect(f.retryable, \"sin `retryable` no se sabe si reintentar\").to.eql(true);","        pm.expect(f.credits_refunded, \"una fuente que falló tiene que devolver sus créditos\").to.be.above(0);","        done();","    });","});"]}}],"response":[{"name":"4. Procuraduría caída (`portal_down`, reintentable) — ejemplo","originalRequest":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key_test}}","type":"text"},{"key":"Idempotency-Key","value":"{{$guid}}","type":"text","description":"Identifica ESTA solicitud. Un reintento por timeout de red con la misma clave devuelve el reporte original —con el header `Idempotent-Replayed: true`— en vez de crear y cobrar otro. Ventana: 24 h. `{{$guid}}` genera una clave nueva en cada envío, que es lo correcto para una solicitud nueva."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/reports/","host":["{{base_url}}"],"path":["api","v1","gateway","api","reports"]},"description":"Procuraduría caída (`portal_down`, reintentable)\n\n\n\nDOCUMENTO SINTÉTICO: 900000004 (CC). Es sintético en el sandbox; no lo uses con una key live.\n\nTipos de documento aceptados: CC, CE, NIT, PA. OJO: el reporte acepta MENOS tipos que la consulta directa por fuente —que admite hasta CC, CE, NIT, PA, PPT y TI según la fuente—. Un tipo fuera de este conjunto NO omite una fuente: rechaza el reporte entero.\n\nQUÉ TIENE QUE PASAR: el reporte cierra `partial` con `overall_status: warning`.","body":{"mode":"raw","raw":"{\n  \"tipo_documento\": \"CC\",\n  \"numero_documento\": \"900000004\",\n  \"selected_endpoints\": [\n    \"contraloria-natural\",\n    \"procuraduria-ordinario\",\n    \"policia-antecedentes\",\n    \"policia-medidas-correctivas\",\n    \"ofac-search\",\n    \"onu-search\",\n    \"pep-search\",\n    \"uk-ofsi-search\",\n    \"eu-sanctions-search\",\n    \"canada-osfi-search\",\n    \"australia-dfat-search\",\n    \"swiss-seco-search\",\n    \"interpol-search\",\n    \"worldbank-debarred-search\"\n  ],\n  \"data_authorization_declared\": true\n}","options":{"raw":{"language":"json"}}}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": \"3f2a8c10-5b7e-4d21-9a44-1c8e6b0d5f93\",\n  \"status\": \"processing\",\n  \"overall_status\": null,\n  \"subject_document_type\": \"CC\",\n  \"subject_document_number\": \"900000004\",\n  \"subject_full_name\": null,\n  \"total_sources\": 14,\n  \"completed_sources\": 0,\n  \"successful_sources\": 0,\n  \"failed_sources\": 0,\n  \"sources\": [],\n  \"total_credits_charged\": 14,\n  \"credits_reserved\": 14,\n  \"credits_refunded\": 0,\n  \"omitted_sources\": [],\n  \"omitted_sources_count\": 0,\n  \"has_pdf\": false,\n  \"pdf_generated_at\": null,\n  \"created_at\": \"2026-09-02T14:05:11Z\",\n  \"completed_at\": null,\n  \"deduplicated\": false,\n  \"origin\": null,\n  \"environment\": \"test\",\n  \"test_mode\": true,\n  \"external_reference\": null,\n  \"correlation_id\": null,\n  \"informational_only\": false,\n  \"informational_sources\": 0,\n  \"conclusive_sources\": 0,\n  \"coverage_sufficient\": false,\n  \"covered_dimensions\": [],\n  \"uncovered_dimensions\": [],\n  \"uncovered_coverage_groups\": [],\n  \"narrative_status\": \"none\",\n  \"risk_analysis\": null,\n  \"risk_narrative\": null,\n  \"narrative_generated_at\": null\n}"}]},{"name":"5. Policía con `timeout` (reintentable)","request":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key_test}}","type":"text"},{"key":"Idempotency-Key","value":"{{$guid}}","type":"text","description":"Identifica ESTA solicitud. Un reintento por timeout de red con la misma clave devuelve el reporte original —con el header `Idempotent-Replayed: true`— en vez de crear y cobrar otro. Ventana: 24 h. `{{$guid}}` genera una clave nueva en cada envío, que es lo correcto para una solicitud nueva."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/reports/","host":["{{base_url}}"],"path":["api","v1","gateway","api","reports"]},"description":"Policía con `timeout` (reintentable)\n\n\n\nDOCUMENTO SINTÉTICO: 900000005 (CC). Es sintético en el sandbox; no lo uses con una key live.\n\nTipos de documento aceptados: CC, CE, NIT, PA. OJO: el reporte acepta MENOS tipos que la consulta directa por fuente —que admite hasta CC, CE, NIT, PA, PPT y TI según la fuente—. Un tipo fuera de este conjunto NO omite una fuente: rechaza el reporte entero.\n\nQUÉ TIENE QUE PASAR: el reporte cierra `partial` con `overall_status: warning`.","body":{"mode":"raw","raw":"{\n  \"tipo_documento\": \"CC\",\n  \"numero_documento\": \"900000005\",\n  \"selected_endpoints\": [\n    \"contraloria-natural\",\n    \"procuraduria-ordinario\",\n    \"policia-antecedentes\",\n    \"policia-medidas-correctivas\",\n    \"ofac-search\",\n    \"onu-search\",\n    \"pep-search\",\n    \"uk-ofsi-search\",\n    \"eu-sanctions-search\",\n    \"canada-osfi-search\",\n    \"australia-dfat-search\",\n    \"swiss-seco-search\",\n    \"interpol-search\",\n    \"worldbank-debarred-search\"\n  ],\n  \"data_authorization_declared\": true\n}","options":{"raw":{"language":"json"}}}},"id":"sbx-policia_timeout","event":[{"listen":"test","script":{"type":"text/javascript","exec":["// El sandbox necesita una key de PRUEBA (`vf_test_…`). Con una de","// producción, esto consultaría portales reales con un documento sintético","// y cobraría créditos: sin key de prueba, las afirmaciones quedan en","// `skipped` con una nota en la consola en vez de en rojo — un rojo por un","// ambiente sin preparar entrena al certificador a ignorar los rojos.","var claveDePrueba = pm.variables.replaceIn(\"{{api_key_test}}\") || \"\";","var esPrueba = claveDePrueba.indexOf(\"vf_test_\") === 0;","if (!esPrueba) {","    console.warn(\"Pegá tu API key de PRUEBA (vf_test_...) en la variable de colección `api_key_test`. Este escenario no se evaluó.\");","}","var t = esPrueba ? pm.test : pm.test.skip;","// Sondeo hasta estado terminal. El sandbox cierra sus tareas asíncronas a","// los pocos segundos (enseña la FORMA del polling, no las latencias","// reales: en producción son p50 40 s / p95 2,1 min).","function sondear(id, intentos, cb) {","    pm.sendRequest({","        url: pm.variables.replaceIn(\"{{base_url}}/api/v1/gateway/api/reports/\") + id,","        method: \"GET\",","        header: { \"X-API-KEY\": claveDePrueba }","    }, function (err, res) {","        if (err) { return cb(err, null); }","        var r = res.json();","        var terminal = [\"completed\", \"partial\", \"failed\"].indexOf(r.status) >= 0;","        if (terminal || intentos <= 1) { return cb(null, r); }","        setTimeout(function () { sondear(id, intentos - 1, cb); }, 1500);","    });","}","","t(\"La creación responde 201 y el reporte NACE EN EL SANDBOX\", function () {","    pm.response.to.have.status(201);","    var r = pm.response.json();","    pm.expect(r.environment, \"el reporte no nació en el sandbox\").to.eql(\"test\");","    pm.expect(r.test_mode, \"`test_mode` es el booleano que un receptor filtra\").to.be.true;","    pm.collectionVariables.set(\"sbx_report_id\", r.id);","});","","t(\"El escenario cierra `partial` con veredicto `warning`\", function (done) {","    sondear(pm.response.json().id, 14, function (err, r) {","        pm.expect(err).to.equal(null);","        pm.expect(r.status, \"el escenario `policia_timeout` no cerró como el banco dice\").to.eql(\"partial\");","        pm.expect(r.overall_status, \"el veredicto no es el del banco\").to.eql(\"warning\");","        var f = r.sources.filter(function (s) { return s.endpoint === \"policia-antecedentes\"; })[0];","        pm.expect(f, \"falta la fuente policia-antecedentes en la respuesta\").to.not.be.undefined;","        pm.expect(f.error_code, \"el canal no declara por qué falló\").to.eql(\"timeout\");","        pm.expect(f.retryable, \"sin `retryable` no se sabe si reintentar\").to.eql(true);","        pm.expect(f.credits_refunded, \"una fuente que falló tiene que devolver sus créditos\").to.be.above(0);","        done();","    });","});"]}}],"response":[{"name":"5. Policía con `timeout` (reintentable) — ejemplo","originalRequest":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key_test}}","type":"text"},{"key":"Idempotency-Key","value":"{{$guid}}","type":"text","description":"Identifica ESTA solicitud. Un reintento por timeout de red con la misma clave devuelve el reporte original —con el header `Idempotent-Replayed: true`— en vez de crear y cobrar otro. Ventana: 24 h. `{{$guid}}` genera una clave nueva en cada envío, que es lo correcto para una solicitud nueva."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/reports/","host":["{{base_url}}"],"path":["api","v1","gateway","api","reports"]},"description":"Policía con `timeout` (reintentable)\n\n\n\nDOCUMENTO SINTÉTICO: 900000005 (CC). Es sintético en el sandbox; no lo uses con una key live.\n\nTipos de documento aceptados: CC, CE, NIT, PA. OJO: el reporte acepta MENOS tipos que la consulta directa por fuente —que admite hasta CC, CE, NIT, PA, PPT y TI según la fuente—. Un tipo fuera de este conjunto NO omite una fuente: rechaza el reporte entero.\n\nQUÉ TIENE QUE PASAR: el reporte cierra `partial` con `overall_status: warning`.","body":{"mode":"raw","raw":"{\n  \"tipo_documento\": \"CC\",\n  \"numero_documento\": \"900000005\",\n  \"selected_endpoints\": [\n    \"contraloria-natural\",\n    \"procuraduria-ordinario\",\n    \"policia-antecedentes\",\n    \"policia-medidas-correctivas\",\n    \"ofac-search\",\n    \"onu-search\",\n    \"pep-search\",\n    \"uk-ofsi-search\",\n    \"eu-sanctions-search\",\n    \"canada-osfi-search\",\n    \"australia-dfat-search\",\n    \"swiss-seco-search\",\n    \"interpol-search\",\n    \"worldbank-debarred-search\"\n  ],\n  \"data_authorization_declared\": true\n}","options":{"raw":{"language":"json"}}}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": \"3f2a8c10-5b7e-4d21-9a44-1c8e6b0d5f93\",\n  \"status\": \"processing\",\n  \"overall_status\": null,\n  \"subject_document_type\": \"CC\",\n  \"subject_document_number\": \"900000005\",\n  \"subject_full_name\": null,\n  \"total_sources\": 14,\n  \"completed_sources\": 0,\n  \"successful_sources\": 0,\n  \"failed_sources\": 0,\n  \"sources\": [],\n  \"total_credits_charged\": 14,\n  \"credits_reserved\": 14,\n  \"credits_refunded\": 0,\n  \"omitted_sources\": [],\n  \"omitted_sources_count\": 0,\n  \"has_pdf\": false,\n  \"pdf_generated_at\": null,\n  \"created_at\": \"2026-09-02T14:05:11Z\",\n  \"completed_at\": null,\n  \"deduplicated\": false,\n  \"origin\": null,\n  \"environment\": \"test\",\n  \"test_mode\": true,\n  \"external_reference\": null,\n  \"correlation_id\": null,\n  \"informational_only\": false,\n  \"informational_sources\": 0,\n  \"conclusive_sources\": 0,\n  \"coverage_sufficient\": false,\n  \"covered_dimensions\": [],\n  \"uncovered_dimensions\": [],\n  \"uncovered_coverage_groups\": [],\n  \"narrative_status\": \"none\",\n  \"risk_analysis\": null,\n  \"risk_narrative\": null,\n  \"narrative_generated_at\": null\n}"}]},{"name":"6. Sujeto que exige autorización del titular (flujo 202)","request":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key_test}}","type":"text"},{"key":"Idempotency-Key","value":"{{$guid}}","type":"text","description":"Identifica ESTA solicitud. Un reintento por timeout de red con la misma clave devuelve el reporte original —con el header `Idempotent-Replayed: true`— en vez de crear y cobrar otro. Ventana: 24 h. `{{$guid}}` genera una clave nueva en cada envío, que es lo correcto para una solicitud nueva."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/reports/","host":["{{base_url}}"],"path":["api","v1","gateway","api","reports"]},"description":"Sujeto que exige autorización del titular (flujo 202)\n\n\n\nDOCUMENTO SINTÉTICO: 900000006 (CC). Es sintético en el sandbox; no lo uses con una key live.\n\nTipos de documento aceptados: CC, CE, NIT, PA. OJO: el reporte acepta MENOS tipos que la consulta directa por fuente —que admite hasta CC, CE, NIT, PA, PPT y TI según la fuente—. Un tipo fuera de este conjunto NO omite una fuente: rechaza el reporte entero.\n\nQUÉ TIENE QUE PASAR: 202 con `consent_id` y, sólo en el sandbox, `sandbox.accept_url` — el enlace con el que se simula la autorización. NO se manda ningún correo.","body":{"mode":"raw","raw":"{\n  \"tipo_documento\": \"CC\",\n  \"numero_documento\": \"900000006\",\n  \"selected_endpoints\": [\n    \"contraloria-natural\",\n    \"procuraduria-ordinario\",\n    \"policia-antecedentes\",\n    \"policia-medidas-correctivas\",\n    \"ofac-search\",\n    \"onu-search\",\n    \"pep-search\",\n    \"uk-ofsi-search\",\n    \"eu-sanctions-search\",\n    \"canada-osfi-search\",\n    \"australia-dfat-search\",\n    \"swiss-seco-search\",\n    \"interpol-search\",\n    \"worldbank-debarred-search\"\n  ],\n  \"data_authorization_declared\": true,\n  \"titular_email\": \"titular.de.prueba@example.com\"\n}","options":{"raw":{"language":"json"}}}},"id":"sbx-consentimiento_202","event":[{"listen":"test","script":{"type":"text/javascript","exec":["// El sandbox necesita una key de PRUEBA (`vf_test_…`). Con una de","// producción, esto consultaría portales reales con un documento sintético","// y cobraría créditos: sin key de prueba, las afirmaciones quedan en","// `skipped` con una nota en la consola en vez de en rojo — un rojo por un","// ambiente sin preparar entrena al certificador a ignorar los rojos.","var claveDePrueba = pm.variables.replaceIn(\"{{api_key_test}}\") || \"\";","var esPrueba = claveDePrueba.indexOf(\"vf_test_\") === 0;","if (!esPrueba) {","    console.warn(\"Pegá tu API key de PRUEBA (vf_test_...) en la variable de colección `api_key_test`. Este escenario no se evaluó.\");","}","var t = esPrueba ? pm.test : pm.test.skip;","","t(\"El sujeto que exige autorización del titular responde 202\", function () {","    pm.response.to.have.status(202);","    var r = pm.response.json();","    pm.expect(r.status).to.eql(\"pending_titular_consent\");","    pm.expect(r.consent_id, \"sin consent_id no hay nada que seguir\").to.be.a(\"string\");","    pm.expect(r.environment).to.eql(\"test\");","});","","t(\"El sandbox NO manda correo y devuelve el enlace de aceptación\", function () {","    var s = pm.response.json().sandbox;","    pm.expect(s, \"sin el bloque `sandbox` el 202 es una promesa que nadie puede cumplir\").to.be.an(\"object\");","    pm.expect(s.email_enviado).to.be.false;","    pm.expect(s.accept_url).to.be.a(\"string\");","    pm.collectionVariables.set(\"sbx_consent_id\", pm.response.json().consent_id);","});","","// Simula la autorización del titular con el `accept_endpoint` del 202","// (la ruta pública, sin API key) y sigue el flujo hasta `granted`.","t(\"Aceptar con accept_endpoint lleva el consentimiento a granted con su report_id\", function (done) {","    var b = pm.response.json();","    var ruta = String(b.sandbox.accept_endpoint || \"\").replace(/^POST\\s+/, \"\");","    var base = pm.variables.replaceIn(\"{{base_url}}\");","    pm.sendRequest({ url: base + ruta, method: \"POST\" }, function (err, res) {","        pm.expect(err).to.equal(null);","        pm.expect(res.code, \"la aceptación del titular falló\").to.eql(200);","        pm.sendRequest({","            url: base + \"/api/v1/gateway/api/consents/\" + b.consent_id,","            method: \"GET\",","            header: { \"X-API-KEY\": claveDePrueba }","        }, function (err2, c) {","            pm.expect(err2).to.equal(null);","            pm.expect(c.code).to.eql(200);","            var x = c.json();","            pm.expect(x.status).to.eql(\"granted\");","            pm.expect(x.report_id, \"granted sin report_id: el reporte es inalcanzable\").to.be.a(\"string\");","            // C2: el documento sale enmascarado y sin datos internos.","            pm.expect(x.subject_document_number, \"el documento del titular tiene que llegar enmascarado\").to.match(/^•+.{0,4}$/);","            [\"user_id\", \"organization_id\", \"token_hash\", \"pending_payload\"].forEach(function (k) {","                pm.expect(x, \"el consentimiento filtra `\" + k + \"`\").to.not.have.property(k);","            });","            pm.collectionVariables.set(\"sbx_report_id\", x.report_id);","            done();","        });","    });","});"]}}],"response":[{"name":"6. Sujeto que exige autorización del titular (flujo 202) — ejemplo","originalRequest":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key_test}}","type":"text"},{"key":"Idempotency-Key","value":"{{$guid}}","type":"text","description":"Identifica ESTA solicitud. Un reintento por timeout de red con la misma clave devuelve el reporte original —con el header `Idempotent-Replayed: true`— en vez de crear y cobrar otro. Ventana: 24 h. `{{$guid}}` genera una clave nueva en cada envío, que es lo correcto para una solicitud nueva."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/reports/","host":["{{base_url}}"],"path":["api","v1","gateway","api","reports"]},"description":"Sujeto que exige autorización del titular (flujo 202)\n\n\n\nDOCUMENTO SINTÉTICO: 900000006 (CC). Es sintético en el sandbox; no lo uses con una key live.\n\nTipos de documento aceptados: CC, CE, NIT, PA. OJO: el reporte acepta MENOS tipos que la consulta directa por fuente —que admite hasta CC, CE, NIT, PA, PPT y TI según la fuente—. Un tipo fuera de este conjunto NO omite una fuente: rechaza el reporte entero.\n\nQUÉ TIENE QUE PASAR: 202 con `consent_id` y, sólo en el sandbox, `sandbox.accept_url` — el enlace con el que se simula la autorización. NO se manda ningún correo.","body":{"mode":"raw","raw":"{\n  \"tipo_documento\": \"CC\",\n  \"numero_documento\": \"900000006\",\n  \"selected_endpoints\": [\n    \"contraloria-natural\",\n    \"procuraduria-ordinario\",\n    \"policia-antecedentes\",\n    \"policia-medidas-correctivas\",\n    \"ofac-search\",\n    \"onu-search\",\n    \"pep-search\",\n    \"uk-ofsi-search\",\n    \"eu-sanctions-search\",\n    \"canada-osfi-search\",\n    \"australia-dfat-search\",\n    \"swiss-seco-search\",\n    \"interpol-search\",\n    \"worldbank-debarred-search\"\n  ],\n  \"data_authorization_declared\": true,\n  \"titular_email\": \"titular.de.prueba@example.com\"\n}","options":{"raw":{"language":"json"}}}},"status":"Accepted","code":202,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"pending_titular_consent\",\n  \"consent_id\": \"b41d7c92-8e5a-4f10-9c33-70a2d6e8b155\",\n  \"consent_status\": \"pending\",\n  \"message\": \"Se envió una solicitud de autorización al titular por correo. La verificación se ejecutará cuando el titular acepte.\",\n  \"environment\": \"test\"\n}"}]},{"name":"7. Parcial mixto: Contraloría sin registros, Medidas correctivas sin responder y Lista ONU sin datos vigentes","request":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key_test}}","type":"text"},{"key":"Idempotency-Key","value":"{{$guid}}","type":"text","description":"Identifica ESTA solicitud. Un reintento por timeout de red con la misma clave devuelve el reporte original —con el header `Idempotent-Replayed: true`— en vez de crear y cobrar otro. Ventana: 24 h. `{{$guid}}` genera una clave nueva en cada envío, que es lo correcto para una solicitud nueva."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/reports/","host":["{{base_url}}"],"path":["api","v1","gateway","api","reports"]},"description":"Parcial mixto: Contraloría sin registros, Medidas correctivas sin responder y Lista ONU sin datos vigentes\n\n\n\nDOCUMENTO SINTÉTICO: 900000007 (CC). Es sintético en el sandbox; no lo uses con una key live.\n\nTipos de documento aceptados: CC, CE, NIT, PA. OJO: el reporte acepta MENOS tipos que la consulta directa por fuente —que admite hasta CC, CE, NIT, PA, PPT y TI según la fuente—. Un tipo fuera de este conjunto NO omite una fuente: rechaza el reporte entero.\n\nQUÉ TIENE QUE PASAR: el reporte cierra `partial` con `overall_status: warning`.","body":{"mode":"raw","raw":"{\n  \"tipo_documento\": \"CC\",\n  \"numero_documento\": \"900000007\",\n  \"selected_endpoints\": [\n    \"contraloria-natural\",\n    \"procuraduria-ordinario\",\n    \"policia-antecedentes\",\n    \"policia-medidas-correctivas\",\n    \"ofac-search\",\n    \"onu-search\",\n    \"pep-search\",\n    \"uk-ofsi-search\",\n    \"eu-sanctions-search\",\n    \"canada-osfi-search\",\n    \"australia-dfat-search\",\n    \"swiss-seco-search\",\n    \"interpol-search\",\n    \"worldbank-debarred-search\"\n  ],\n  \"data_authorization_declared\": true\n}","options":{"raw":{"language":"json"}}}},"id":"sbx-parcial_mixto","event":[{"listen":"test","script":{"type":"text/javascript","exec":["// El sandbox necesita una key de PRUEBA (`vf_test_…`). Con una de","// producción, esto consultaría portales reales con un documento sintético","// y cobraría créditos: sin key de prueba, las afirmaciones quedan en","// `skipped` con una nota en la consola en vez de en rojo — un rojo por un","// ambiente sin preparar entrena al certificador a ignorar los rojos.","var claveDePrueba = pm.variables.replaceIn(\"{{api_key_test}}\") || \"\";","var esPrueba = claveDePrueba.indexOf(\"vf_test_\") === 0;","if (!esPrueba) {","    console.warn(\"Pegá tu API key de PRUEBA (vf_test_...) en la variable de colección `api_key_test`. Este escenario no se evaluó.\");","}","var t = esPrueba ? pm.test : pm.test.skip;","// Sondeo hasta estado terminal. El sandbox cierra sus tareas asíncronas a","// los pocos segundos (enseña la FORMA del polling, no las latencias","// reales: en producción son p50 40 s / p95 2,1 min).","function sondear(id, intentos, cb) {","    pm.sendRequest({","        url: pm.variables.replaceIn(\"{{base_url}}/api/v1/gateway/api/reports/\") + id,","        method: \"GET\",","        header: { \"X-API-KEY\": claveDePrueba }","    }, function (err, res) {","        if (err) { return cb(err, null); }","        var r = res.json();","        var terminal = [\"completed\", \"partial\", \"failed\"].indexOf(r.status) >= 0;","        if (terminal || intentos <= 1) { return cb(null, r); }","        setTimeout(function () { sondear(id, intentos - 1, cb); }, 1500);","    });","}","","t(\"La creación responde 201 y el reporte NACE EN EL SANDBOX\", function () {","    pm.response.to.have.status(201);","    var r = pm.response.json();","    pm.expect(r.environment, \"el reporte no nació en el sandbox\").to.eql(\"test\");","    pm.expect(r.test_mode, \"`test_mode` es el booleano que un receptor filtra\").to.be.true;","    pm.collectionVariables.set(\"sbx_report_id\", r.id);","});","","t(\"El escenario cierra `partial` con veredicto `warning`\", function (done) {","    sondear(pm.response.json().id, 14, function (err, r) {","        pm.expect(err).to.equal(null);","        pm.expect(r.status, \"el escenario `parcial_mixto` no cerró como el banco dice\").to.eql(\"partial\");","        pm.expect(r.overall_status, \"el veredicto no es el del banco\").to.eql(\"warning\");","        var f = r.sources.filter(function (s) { return s.endpoint === \"policia-medidas-correctivas\"; })[0];","        pm.expect(f, \"falta la fuente policia-medidas-correctivas en la respuesta\").to.not.be.undefined;","        pm.expect(f.error_code, \"el canal no declara por qué falló\").to.eql(\"captcha\");","        pm.expect(f.retryable, \"sin `retryable` no se sabe si reintentar\").to.eql(true);","        pm.expect(f.credits_refunded, \"una fuente que falló tiene que devolver sus créditos\").to.be.above(0);","        done();","    });","});"]}}],"response":[{"name":"7. Parcial mixto: Contraloría sin registros, Medidas correctivas sin responder y Lista ONU sin datos vigentes — ejemplo","originalRequest":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key_test}}","type":"text"},{"key":"Idempotency-Key","value":"{{$guid}}","type":"text","description":"Identifica ESTA solicitud. Un reintento por timeout de red con la misma clave devuelve el reporte original —con el header `Idempotent-Replayed: true`— en vez de crear y cobrar otro. Ventana: 24 h. `{{$guid}}` genera una clave nueva en cada envío, que es lo correcto para una solicitud nueva."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/reports/","host":["{{base_url}}"],"path":["api","v1","gateway","api","reports"]},"description":"Parcial mixto: Contraloría sin registros, Medidas correctivas sin responder y Lista ONU sin datos vigentes\n\n\n\nDOCUMENTO SINTÉTICO: 900000007 (CC). Es sintético en el sandbox; no lo uses con una key live.\n\nTipos de documento aceptados: CC, CE, NIT, PA. OJO: el reporte acepta MENOS tipos que la consulta directa por fuente —que admite hasta CC, CE, NIT, PA, PPT y TI según la fuente—. Un tipo fuera de este conjunto NO omite una fuente: rechaza el reporte entero.\n\nQUÉ TIENE QUE PASAR: el reporte cierra `partial` con `overall_status: warning`.","body":{"mode":"raw","raw":"{\n  \"tipo_documento\": \"CC\",\n  \"numero_documento\": \"900000007\",\n  \"selected_endpoints\": [\n    \"contraloria-natural\",\n    \"procuraduria-ordinario\",\n    \"policia-antecedentes\",\n    \"policia-medidas-correctivas\",\n    \"ofac-search\",\n    \"onu-search\",\n    \"pep-search\",\n    \"uk-ofsi-search\",\n    \"eu-sanctions-search\",\n    \"canada-osfi-search\",\n    \"australia-dfat-search\",\n    \"swiss-seco-search\",\n    \"interpol-search\",\n    \"worldbank-debarred-search\"\n  ],\n  \"data_authorization_declared\": true\n}","options":{"raw":{"language":"json"}}}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": \"3f2a8c10-5b7e-4d21-9a44-1c8e6b0d5f93\",\n  \"status\": \"processing\",\n  \"overall_status\": null,\n  \"subject_document_type\": \"CC\",\n  \"subject_document_number\": \"900000007\",\n  \"subject_full_name\": null,\n  \"total_sources\": 14,\n  \"completed_sources\": 0,\n  \"successful_sources\": 0,\n  \"failed_sources\": 0,\n  \"sources\": [],\n  \"total_credits_charged\": 14,\n  \"credits_reserved\": 14,\n  \"credits_refunded\": 0,\n  \"omitted_sources\": [],\n  \"omitted_sources_count\": 0,\n  \"has_pdf\": false,\n  \"pdf_generated_at\": null,\n  \"created_at\": \"2026-09-02T14:05:11Z\",\n  \"completed_at\": null,\n  \"deduplicated\": false,\n  \"origin\": null,\n  \"environment\": \"test\",\n  \"test_mode\": true,\n  \"external_reference\": null,\n  \"correlation_id\": null,\n  \"informational_only\": false,\n  \"informational_sources\": 0,\n  \"conclusive_sources\": 0,\n  \"coverage_sufficient\": false,\n  \"covered_dimensions\": [],\n  \"uncovered_dimensions\": [],\n  \"uncovered_coverage_groups\": [],\n  \"narrative_status\": \"none\",\n  \"risk_analysis\": null,\n  \"risk_narrative\": null,\n  \"narrative_generated_at\": null\n}"}]},{"name":"8. Persona jurídica: Contraloría PJ y Procuraduría limpias, RUES","request":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key_test}}","type":"text"},{"key":"Idempotency-Key","value":"{{$guid}}","type":"text","description":"Identifica ESTA solicitud. Un reintento por timeout de red con la misma clave devuelve el reporte original —con el header `Idempotent-Replayed: true`— en vez de crear y cobrar otro. Ventana: 24 h. `{{$guid}}` genera una clave nueva en cada envío, que es lo correcto para una solicitud nueva."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/reports/","host":["{{base_url}}"],"path":["api","v1","gateway","api","reports"]},"description":"Persona jurídica: Contraloría PJ y Procuraduría limpias, RUES\n\n\n\nDOCUMENTO SINTÉTICO: 900000008 (NIT). Es sintético en el sandbox; no lo uses con una key live.\n\nTipos de documento aceptados: CC, CE, NIT, PA. OJO: el reporte acepta MENOS tipos que la consulta directa por fuente —que admite hasta CC, CE, NIT, PA, PPT y TI según la fuente—. Un tipo fuera de este conjunto NO omite una fuente: rechaza el reporte entero.\n\nQUÉ TIENE QUE PASAR: el reporte cierra `completed` con `overall_status: clean`.","body":{"mode":"raw","raw":"{\n  \"tipo_documento\": \"NIT\",\n  \"numero_documento\": \"900000008\",\n  \"selected_endpoints\": [\n    \"contraloria-juridica\",\n    \"procuraduria-ordinario\",\n    \"rues-consultar\",\n    \"ofac-search\",\n    \"onu-search\",\n    \"uk-ofsi-search\",\n    \"eu-sanctions-search\",\n    \"canada-osfi-search\",\n    \"australia-dfat-search\",\n    \"swiss-seco-search\",\n    \"interpol-search\",\n    \"worldbank-debarred-search\"\n  ],\n  \"data_authorization_declared\": true\n}","options":{"raw":{"language":"json"}}}},"id":"sbx-juridica_limpia","event":[{"listen":"test","script":{"type":"text/javascript","exec":["// El sandbox necesita una key de PRUEBA (`vf_test_…`). Con una de","// producción, esto consultaría portales reales con un documento sintético","// y cobraría créditos: sin key de prueba, las afirmaciones quedan en","// `skipped` con una nota en la consola en vez de en rojo — un rojo por un","// ambiente sin preparar entrena al certificador a ignorar los rojos.","var claveDePrueba = pm.variables.replaceIn(\"{{api_key_test}}\") || \"\";","var esPrueba = claveDePrueba.indexOf(\"vf_test_\") === 0;","if (!esPrueba) {","    console.warn(\"Pegá tu API key de PRUEBA (vf_test_...) en la variable de colección `api_key_test`. Este escenario no se evaluó.\");","}","var t = esPrueba ? pm.test : pm.test.skip;","// Sondeo hasta estado terminal. El sandbox cierra sus tareas asíncronas a","// los pocos segundos (enseña la FORMA del polling, no las latencias","// reales: en producción son p50 40 s / p95 2,1 min).","function sondear(id, intentos, cb) {","    pm.sendRequest({","        url: pm.variables.replaceIn(\"{{base_url}}/api/v1/gateway/api/reports/\") + id,","        method: \"GET\",","        header: { \"X-API-KEY\": claveDePrueba }","    }, function (err, res) {","        if (err) { return cb(err, null); }","        var r = res.json();","        var terminal = [\"completed\", \"partial\", \"failed\"].indexOf(r.status) >= 0;","        if (terminal || intentos <= 1) { return cb(null, r); }","        setTimeout(function () { sondear(id, intentos - 1, cb); }, 1500);","    });","}","","t(\"La creación responde 201 y el reporte NACE EN EL SANDBOX\", function () {","    pm.response.to.have.status(201);","    var r = pm.response.json();","    pm.expect(r.environment, \"el reporte no nació en el sandbox\").to.eql(\"test\");","    pm.expect(r.test_mode, \"`test_mode` es el booleano que un receptor filtra\").to.be.true;","    pm.collectionVariables.set(\"sbx_report_id\", r.id);","});","","t(\"El escenario cierra `completed` con veredicto `clean`\", function (done) {","    sondear(pm.response.json().id, 14, function (err, r) {","        pm.expect(err).to.equal(null);","        pm.expect(r.status, \"el escenario `juridica_limpia` no cerró como el banco dice\").to.eql(\"completed\");","        pm.expect(r.overall_status, \"el veredicto no es el del banco\").to.eql(\"clean\");","        done();","    });","});"]}}],"response":[{"name":"8. Persona jurídica: Contraloría PJ y Procuraduría limpias, RUES — ejemplo","originalRequest":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key_test}}","type":"text"},{"key":"Idempotency-Key","value":"{{$guid}}","type":"text","description":"Identifica ESTA solicitud. Un reintento por timeout de red con la misma clave devuelve el reporte original —con el header `Idempotent-Replayed: true`— en vez de crear y cobrar otro. Ventana: 24 h. `{{$guid}}` genera una clave nueva en cada envío, que es lo correcto para una solicitud nueva."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/reports/","host":["{{base_url}}"],"path":["api","v1","gateway","api","reports"]},"description":"Persona jurídica: Contraloría PJ y Procuraduría limpias, RUES\n\n\n\nDOCUMENTO SINTÉTICO: 900000008 (NIT). Es sintético en el sandbox; no lo uses con una key live.\n\nTipos de documento aceptados: CC, CE, NIT, PA. OJO: el reporte acepta MENOS tipos que la consulta directa por fuente —que admite hasta CC, CE, NIT, PA, PPT y TI según la fuente—. Un tipo fuera de este conjunto NO omite una fuente: rechaza el reporte entero.\n\nQUÉ TIENE QUE PASAR: el reporte cierra `completed` con `overall_status: clean`.","body":{"mode":"raw","raw":"{\n  \"tipo_documento\": \"NIT\",\n  \"numero_documento\": \"900000008\",\n  \"selected_endpoints\": [\n    \"contraloria-juridica\",\n    \"procuraduria-ordinario\",\n    \"rues-consultar\",\n    \"ofac-search\",\n    \"onu-search\",\n    \"uk-ofsi-search\",\n    \"eu-sanctions-search\",\n    \"canada-osfi-search\",\n    \"australia-dfat-search\",\n    \"swiss-seco-search\",\n    \"interpol-search\",\n    \"worldbank-debarred-search\"\n  ],\n  \"data_authorization_declared\": true\n}","options":{"raw":{"language":"json"}}}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": \"3f2a8c10-5b7e-4d21-9a44-1c8e6b0d5f93\",\n  \"status\": \"processing\",\n  \"overall_status\": null,\n  \"subject_document_type\": \"NIT\",\n  \"subject_document_number\": \"900000008\",\n  \"subject_full_name\": null,\n  \"total_sources\": 12,\n  \"completed_sources\": 0,\n  \"successful_sources\": 0,\n  \"failed_sources\": 0,\n  \"sources\": [],\n  \"total_credits_charged\": 12,\n  \"credits_reserved\": 12,\n  \"credits_refunded\": 0,\n  \"omitted_sources\": [],\n  \"omitted_sources_count\": 0,\n  \"has_pdf\": false,\n  \"pdf_generated_at\": null,\n  \"created_at\": \"2026-09-02T14:05:11Z\",\n  \"completed_at\": null,\n  \"deduplicated\": false,\n  \"origin\": null,\n  \"environment\": \"test\",\n  \"test_mode\": true,\n  \"external_reference\": null,\n  \"correlation_id\": null,\n  \"informational_only\": false,\n  \"informational_sources\": 0,\n  \"conclusive_sources\": 0,\n  \"coverage_sufficient\": false,\n  \"covered_dimensions\": [],\n  \"uncovered_dimensions\": [],\n  \"uncovered_coverage_groups\": [],\n  \"narrative_status\": \"none\",\n  \"risk_analysis\": null,\n  \"risk_narrative\": null,\n  \"narrative_generated_at\": null\n}"}]},{"name":"9. Sujeto que agota el saldo de prueba (402)","request":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key_test}}","type":"text"},{"key":"Idempotency-Key","value":"{{$guid}}","type":"text","description":"Identifica ESTA solicitud. Un reintento por timeout de red con la misma clave devuelve el reporte original —con el header `Idempotent-Replayed: true`— en vez de crear y cobrar otro. Ventana: 24 h. `{{$guid}}` genera una clave nueva en cada envío, que es lo correcto para una solicitud nueva."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/reports/","host":["{{base_url}}"],"path":["api","v1","gateway","api","reports"]},"description":"Sujeto que agota el saldo de prueba (402)\n\n\n\nDOCUMENTO SINTÉTICO: 900000009 (CC). Es sintético en el sandbox; no lo uses con una key live.\n\nTipos de documento aceptados: CC, CE, NIT, PA. OJO: el reporte acepta MENOS tipos que la consulta directa por fuente —que admite hasta CC, CE, NIT, PA, PPT y TI según la fuente—. Un tipo fuera de este conjunto NO omite una fuente: rechaza el reporte entero.\n\nQUÉ TIENE QUE PASAR: 402 `INSUFFICIENT_CREDITS`, con la `Idempotency-Key` LIBERADA (reintentarla no da 409).","body":{"mode":"raw","raw":"{\n  \"tipo_documento\": \"CC\",\n  \"numero_documento\": \"900000009\",\n  \"selected_endpoints\": [\n    \"contraloria-natural\"\n  ],\n  \"data_authorization_declared\": true\n}","options":{"raw":{"language":"json"}}}},"id":"sbx-sin_saldo","event":[{"listen":"test","script":{"type":"text/javascript","exec":["// El sandbox necesita una key de PRUEBA (`vf_test_…`). Con una de","// producción, esto consultaría portales reales con un documento sintético","// y cobraría créditos: sin key de prueba, las afirmaciones quedan en","// `skipped` con una nota en la consola en vez de en rojo — un rojo por un","// ambiente sin preparar entrena al certificador a ignorar los rojos.","var claveDePrueba = pm.variables.replaceIn(\"{{api_key_test}}\") || \"\";","var esPrueba = claveDePrueba.indexOf(\"vf_test_\") === 0;","if (!esPrueba) {","    console.warn(\"Pegá tu API key de PRUEBA (vf_test_...) en la variable de colección `api_key_test`. Este escenario no se evaluó.\");","}","var t = esPrueba ? pm.test : pm.test.skip;","","t(\"El escenario del saldo insuficiente responde 402 INSUFFICIENT_CREDITS\", function () {","    pm.response.to.have.status(402);","    var e = pm.response.json().error;","    pm.expect(e.code).to.eql(\"INSUFFICIENT_CREDITS\");","});","","t(\"El 402 NO cobra y NO quema la Idempotency-Key\", function () {","    pm.expect(pm.response.headers.has(\"Idempotent-Replayed\"),","        \"un 402 no puede anunciarse como replay\").to.be.false;","});"]}}],"response":[{"name":"9. Sujeto que agota el saldo de prueba (402) — ejemplo","originalRequest":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key_test}}","type":"text"},{"key":"Idempotency-Key","value":"{{$guid}}","type":"text","description":"Identifica ESTA solicitud. Un reintento por timeout de red con la misma clave devuelve el reporte original —con el header `Idempotent-Replayed: true`— en vez de crear y cobrar otro. Ventana: 24 h. `{{$guid}}` genera una clave nueva en cada envío, que es lo correcto para una solicitud nueva."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/reports/","host":["{{base_url}}"],"path":["api","v1","gateway","api","reports"]},"description":"Sujeto que agota el saldo de prueba (402)\n\n\n\nDOCUMENTO SINTÉTICO: 900000009 (CC). Es sintético en el sandbox; no lo uses con una key live.\n\nTipos de documento aceptados: CC, CE, NIT, PA. OJO: el reporte acepta MENOS tipos que la consulta directa por fuente —que admite hasta CC, CE, NIT, PA, PPT y TI según la fuente—. Un tipo fuera de este conjunto NO omite una fuente: rechaza el reporte entero.\n\nQUÉ TIENE QUE PASAR: 402 `INSUFFICIENT_CREDITS`, con la `Idempotency-Key` LIBERADA (reintentarla no da 409).","body":{"mode":"raw","raw":"{\n  \"tipo_documento\": \"CC\",\n  \"numero_documento\": \"900000009\",\n  \"selected_endpoints\": [\n    \"contraloria-natural\"\n  ],\n  \"data_authorization_declared\": true\n}","options":{"raw":{"language":"json"}}}},"status":"Payment Required","code":402,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"detail\": \"Créditos insuficientes. Se necesitan 1 y hay 0 disponibles en el saldo de prueba.\",\n  \"success\": false,\n  \"error\": {\n    \"code\": \"INSUFFICIENT_CREDITS\",\n    \"message\": \"Créditos insuficientes. Se necesitan 1 y hay 0 disponibles en el saldo de prueba.\"\n  }\n}"}]},{"name":"10. Tarea que nunca llega a estado terminal","request":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key_test}}","type":"text"},{"key":"Idempotency-Key","value":"{{$guid}}","type":"text","description":"Identifica ESTA solicitud. Un reintento por timeout de red con la misma clave devuelve el reporte original —con el header `Idempotent-Replayed: true`— en vez de crear y cobrar otro. Ventana: 24 h. `{{$guid}}` genera una clave nueva en cada envío, que es lo correcto para una solicitud nueva."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/reports/","host":["{{base_url}}"],"path":["api","v1","gateway","api","reports"]},"description":"Tarea que nunca llega a estado terminal\n\n\n\nDOCUMENTO SINTÉTICO: 900000015 (CC). Es sintético en el sandbox; no lo uses con una key live.\n\nTipos de documento aceptados: CC, CE, NIT, PA. OJO: el reporte acepta MENOS tipos que la consulta directa por fuente —que admite hasta CC, CE, NIT, PA, PPT y TI según la fuente—. Un tipo fuera de este conjunto NO omite una fuente: rechaza el reporte entero.\n\nQUÉ TIENE QUE PASAR: la tarea NUNCA llega a estado terminal. Es para que pruebes TU timeout de polling sin esperar a que un portal real se cuelgue.","body":{"mode":"raw","raw":"{\n  \"tipo_documento\": \"CC\",\n  \"numero_documento\": \"900000015\",\n  \"selected_endpoints\": [\n    \"policia-antecedentes\"\n  ],\n  \"data_authorization_declared\": true\n}","options":{"raw":{"language":"json"}}}},"id":"sbx-tarea_que_nunca_cierra","event":[{"listen":"test","script":{"type":"text/javascript","exec":["// El sandbox necesita una key de PRUEBA (`vf_test_…`). Con una de","// producción, esto consultaría portales reales con un documento sintético","// y cobraría créditos: sin key de prueba, las afirmaciones quedan en","// `skipped` con una nota en la consola en vez de en rojo — un rojo por un","// ambiente sin preparar entrena al certificador a ignorar los rojos.","var claveDePrueba = pm.variables.replaceIn(\"{{api_key_test}}\") || \"\";","var esPrueba = claveDePrueba.indexOf(\"vf_test_\") === 0;","if (!esPrueba) {","    console.warn(\"Pegá tu API key de PRUEBA (vf_test_...) en la variable de colección `api_key_test`. Este escenario no se evaluó.\");","}","var t = esPrueba ? pm.test : pm.test.skip;","// Sondeo hasta estado terminal. El sandbox cierra sus tareas asíncronas a","// los pocos segundos (enseña la FORMA del polling, no las latencias","// reales: en producción son p50 40 s / p95 2,1 min).","function sondear(id, intentos, cb) {","    pm.sendRequest({","        url: pm.variables.replaceIn(\"{{base_url}}/api/v1/gateway/api/reports/\") + id,","        method: \"GET\",","        header: { \"X-API-KEY\": claveDePrueba }","    }, function (err, res) {","        if (err) { return cb(err, null); }","        var r = res.json();","        var terminal = [\"completed\", \"partial\", \"failed\"].indexOf(r.status) >= 0;","        if (terminal || intentos <= 1) { return cb(null, r); }","        setTimeout(function () { sondear(id, intentos - 1, cb); }, 1500);","    });","}","","t(\"La creación responde 201 y el reporte NACE EN EL SANDBOX\", function () {","    pm.response.to.have.status(201);","    var r = pm.response.json();","    pm.expect(r.environment, \"el reporte no nació en el sandbox\").to.eql(\"test\");","    pm.expect(r.test_mode, \"`test_mode` es el booleano que un receptor filtra\").to.be.true;","    pm.collectionVariables.set(\"sbx_report_id\", r.id);","});","","t(\"La tarea que nunca cierra sigue `processing` tras el sondeo\", function (done) {","    sondear(pm.response.json().id, 4, function (err, r) {","        pm.expect(err).to.equal(null);","        pm.expect([\"pending\", \"processing\"],","            \"este escenario NO puede llegar a estado terminal: existe para que \"","            + \"pruebes TU timeout de polling\").to.include(r.status);","        done();","    });","});"]}}],"response":[{"name":"10. Tarea que nunca llega a estado terminal — ejemplo","originalRequest":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key_test}}","type":"text"},{"key":"Idempotency-Key","value":"{{$guid}}","type":"text","description":"Identifica ESTA solicitud. Un reintento por timeout de red con la misma clave devuelve el reporte original —con el header `Idempotent-Replayed: true`— en vez de crear y cobrar otro. Ventana: 24 h. `{{$guid}}` genera una clave nueva en cada envío, que es lo correcto para una solicitud nueva."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/reports/","host":["{{base_url}}"],"path":["api","v1","gateway","api","reports"]},"description":"Tarea que nunca llega a estado terminal\n\n\n\nDOCUMENTO SINTÉTICO: 900000015 (CC). Es sintético en el sandbox; no lo uses con una key live.\n\nTipos de documento aceptados: CC, CE, NIT, PA. OJO: el reporte acepta MENOS tipos que la consulta directa por fuente —que admite hasta CC, CE, NIT, PA, PPT y TI según la fuente—. Un tipo fuera de este conjunto NO omite una fuente: rechaza el reporte entero.\n\nQUÉ TIENE QUE PASAR: la tarea NUNCA llega a estado terminal. Es para que pruebes TU timeout de polling sin esperar a que un portal real se cuelgue.","body":{"mode":"raw","raw":"{\n  \"tipo_documento\": \"CC\",\n  \"numero_documento\": \"900000015\",\n  \"selected_endpoints\": [\n    \"policia-antecedentes\"\n  ],\n  \"data_authorization_declared\": true\n}","options":{"raw":{"language":"json"}}}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": \"3f2a8c10-5b7e-4d21-9a44-1c8e6b0d5f93\",\n  \"status\": \"processing\",\n  \"overall_status\": null,\n  \"subject_document_type\": \"CC\",\n  \"subject_document_number\": \"900000015\",\n  \"subject_full_name\": null,\n  \"total_sources\": 1,\n  \"completed_sources\": 0,\n  \"successful_sources\": 0,\n  \"failed_sources\": 0,\n  \"sources\": [],\n  \"total_credits_charged\": 1,\n  \"credits_reserved\": 1,\n  \"credits_refunded\": 0,\n  \"omitted_sources\": [],\n  \"omitted_sources_count\": 0,\n  \"has_pdf\": false,\n  \"pdf_generated_at\": null,\n  \"created_at\": \"2026-09-02T14:05:11Z\",\n  \"completed_at\": null,\n  \"deduplicated\": false,\n  \"origin\": null,\n  \"environment\": \"test\",\n  \"test_mode\": true,\n  \"external_reference\": null,\n  \"correlation_id\": null,\n  \"informational_only\": false,\n  \"informational_sources\": 0,\n  \"conclusive_sources\": 0,\n  \"coverage_sufficient\": false,\n  \"covered_dimensions\": [],\n  \"uncovered_dimensions\": [],\n  \"uncovered_coverage_groups\": [],\n  \"narrative_status\": \"none\",\n  \"risk_analysis\": null,\n  \"risk_narrative\": null,\n  \"narrative_generated_at\": null\n}"}]},{"name":"11. Documento no reservado — responde limpio","request":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key_test}}","type":"text"},{"key":"Idempotency-Key","value":"{{$guid}}","type":"text","description":"Identifica ESTA solicitud. Un reintento por timeout de red con la misma clave devuelve el reporte original —con el header `Idempotent-Replayed: true`— en vez de crear y cobrar otro. Ventana: 24 h. `{{$guid}}` genera una clave nueva en cada envío, que es lo correcto para una solicitud nueva."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/reports/","host":["{{base_url}}"],"path":["api","v1","gateway","api","reports"]},"description":"Documento no reservado — responde limpio\n\n\n\nDOCUMENTO SINTÉTICO: 900000099 (CC). Es sintético en el sandbox; no lo uses con una key live.\n\nTipos de documento aceptados: CC, CE, NIT, PA. OJO: el reporte acepta MENOS tipos que la consulta directa por fuente —que admite hasta CC, CE, NIT, PA, PPT y TI según la fuente—. Un tipo fuera de este conjunto NO omite una fuente: rechaza el reporte entero.\n\nQUÉ TIENE QUE PASAR: el reporte cierra `completed` con `overall_status: clean`.","body":{"mode":"raw","raw":"{\n  \"tipo_documento\": \"CC\",\n  \"numero_documento\": \"900000099\",\n  \"selected_endpoints\": [\n    \"contraloria-natural\",\n    \"procuraduria-ordinario\",\n    \"policia-antecedentes\",\n    \"policia-medidas-correctivas\",\n    \"ofac-search\",\n    \"onu-search\",\n    \"pep-search\",\n    \"uk-ofsi-search\",\n    \"eu-sanctions-search\",\n    \"canada-osfi-search\",\n    \"australia-dfat-search\",\n    \"swiss-seco-search\",\n    \"interpol-search\",\n    \"worldbank-debarred-search\"\n  ],\n  \"data_authorization_declared\": true\n}","options":{"raw":{"language":"json"}}}},"id":"sbx-default","event":[{"listen":"test","script":{"type":"text/javascript","exec":["// El sandbox necesita una key de PRUEBA (`vf_test_…`). Con una de","// producción, esto consultaría portales reales con un documento sintético","// y cobraría créditos: sin key de prueba, las afirmaciones quedan en","// `skipped` con una nota en la consola en vez de en rojo — un rojo por un","// ambiente sin preparar entrena al certificador a ignorar los rojos.","var claveDePrueba = pm.variables.replaceIn(\"{{api_key_test}}\") || \"\";","var esPrueba = claveDePrueba.indexOf(\"vf_test_\") === 0;","if (!esPrueba) {","    console.warn(\"Pegá tu API key de PRUEBA (vf_test_...) en la variable de colección `api_key_test`. Este escenario no se evaluó.\");","}","var t = esPrueba ? pm.test : pm.test.skip;","// Sondeo hasta estado terminal. El sandbox cierra sus tareas asíncronas a","// los pocos segundos (enseña la FORMA del polling, no las latencias","// reales: en producción son p50 40 s / p95 2,1 min).","function sondear(id, intentos, cb) {","    pm.sendRequest({","        url: pm.variables.replaceIn(\"{{base_url}}/api/v1/gateway/api/reports/\") + id,","        method: \"GET\",","        header: { \"X-API-KEY\": claveDePrueba }","    }, function (err, res) {","        if (err) { return cb(err, null); }","        var r = res.json();","        var terminal = [\"completed\", \"partial\", \"failed\"].indexOf(r.status) >= 0;","        if (terminal || intentos <= 1) { return cb(null, r); }","        setTimeout(function () { sondear(id, intentos - 1, cb); }, 1500);","    });","}","","t(\"La creación responde 201 y el reporte NACE EN EL SANDBOX\", function () {","    pm.response.to.have.status(201);","    var r = pm.response.json();","    pm.expect(r.environment, \"el reporte no nació en el sandbox\").to.eql(\"test\");","    pm.expect(r.test_mode, \"`test_mode` es el booleano que un receptor filtra\").to.be.true;","    pm.collectionVariables.set(\"sbx_report_id\", r.id);","});","","t(\"El escenario cierra `completed` con veredicto `clean`\", function (done) {","    sondear(pm.response.json().id, 14, function (err, r) {","        pm.expect(err).to.equal(null);","        pm.expect(r.status, \"el escenario `default` no cerró como el banco dice\").to.eql(\"completed\");","        pm.expect(r.overall_status, \"el veredicto no es el del banco\").to.eql(\"clean\");","        done();","    });","});"]}}],"response":[{"name":"11. Documento no reservado — responde limpio — ejemplo","originalRequest":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key_test}}","type":"text"},{"key":"Idempotency-Key","value":"{{$guid}}","type":"text","description":"Identifica ESTA solicitud. Un reintento por timeout de red con la misma clave devuelve el reporte original —con el header `Idempotent-Replayed: true`— en vez de crear y cobrar otro. Ventana: 24 h. `{{$guid}}` genera una clave nueva en cada envío, que es lo correcto para una solicitud nueva."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/reports/","host":["{{base_url}}"],"path":["api","v1","gateway","api","reports"]},"description":"Documento no reservado — responde limpio\n\n\n\nDOCUMENTO SINTÉTICO: 900000099 (CC). Es sintético en el sandbox; no lo uses con una key live.\n\nTipos de documento aceptados: CC, CE, NIT, PA. OJO: el reporte acepta MENOS tipos que la consulta directa por fuente —que admite hasta CC, CE, NIT, PA, PPT y TI según la fuente—. Un tipo fuera de este conjunto NO omite una fuente: rechaza el reporte entero.\n\nQUÉ TIENE QUE PASAR: el reporte cierra `completed` con `overall_status: clean`.","body":{"mode":"raw","raw":"{\n  \"tipo_documento\": \"CC\",\n  \"numero_documento\": \"900000099\",\n  \"selected_endpoints\": [\n    \"contraloria-natural\",\n    \"procuraduria-ordinario\",\n    \"policia-antecedentes\",\n    \"policia-medidas-correctivas\",\n    \"ofac-search\",\n    \"onu-search\",\n    \"pep-search\",\n    \"uk-ofsi-search\",\n    \"eu-sanctions-search\",\n    \"canada-osfi-search\",\n    \"australia-dfat-search\",\n    \"swiss-seco-search\",\n    \"interpol-search\",\n    \"worldbank-debarred-search\"\n  ],\n  \"data_authorization_declared\": true\n}","options":{"raw":{"language":"json"}}}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": \"3f2a8c10-5b7e-4d21-9a44-1c8e6b0d5f93\",\n  \"status\": \"processing\",\n  \"overall_status\": null,\n  \"subject_document_type\": \"CC\",\n  \"subject_document_number\": \"900000099\",\n  \"subject_full_name\": null,\n  \"total_sources\": 14,\n  \"completed_sources\": 0,\n  \"successful_sources\": 0,\n  \"failed_sources\": 0,\n  \"sources\": [],\n  \"total_credits_charged\": 14,\n  \"credits_reserved\": 14,\n  \"credits_refunded\": 0,\n  \"omitted_sources\": [],\n  \"omitted_sources_count\": 0,\n  \"has_pdf\": false,\n  \"pdf_generated_at\": null,\n  \"created_at\": \"2026-09-02T14:05:11Z\",\n  \"completed_at\": null,\n  \"deduplicated\": false,\n  \"origin\": null,\n  \"environment\": \"test\",\n  \"test_mode\": true,\n  \"external_reference\": null,\n  \"correlation_id\": null,\n  \"informational_only\": false,\n  \"informational_sources\": 0,\n  \"conclusive_sources\": 0,\n  \"coverage_sufficient\": false,\n  \"covered_dimensions\": [],\n  \"uncovered_dimensions\": [],\n  \"uncovered_coverage_groups\": [],\n  \"narrative_status\": \"none\",\n  \"risk_analysis\": null,\n  \"risk_narrative\": null,\n  \"narrative_generated_at\": null\n}"}]}],"description":"Los escenarios que hacen falta para certificar el canal SIN consultar a ninguna persona real y SIN gastar un crédito: coincidencia firme en OFAC, PEP en revisión, portal caído, timeout, captcha, lista vencida, 402 por saldo, el flujo 202 del titular y una tarea que nunca cierra.\n\nANTES DE CORRER\n1. Pegá tu API key de PRUEBA (`vf_test_…`) en la variable `api_key_test`. Es OTRA variable que `api_key` a propósito: con una key de PRODUCCIÓN estos documentos sintéticos se consultarían contra los portales reales y se cobrarían créditos. Por eso la carpeta trae una guarda que corre ANTES de cada envío: si `api_key_test` no empieza con `vf_test_`, el request NO SALE (queda fuera de la corrida con un aviso en la consola).\n2. Corré la carpeta entera con el Collection Runner: cada request hace su propio sondeo hasta el estado terminal.\n\nEL SALDO DE PRUEBA es propio, se repone hasta 1.000 créditos todas las noches y NO toca el saldo que compraste. Los reportes del sandbox tampoco se mezclan con los reales: no aparecen en el listado de una key live, su PDF lleva la marca «PRUEBA — DATOS SINTÉTICOS» y se borran solos a los 7 días.\n\nCUALQUIER OTRO DOCUMENTO responde limpio: podés usar los de tu propia suite sin adoptar los nuestros.\n\nSIN `selected_endpoints`, el reporte del sandbox incluye sólo las fuentes con escenario en el banco: las demás van a `omitted_sources` con `reason: \"not_in_sandbox\"` (no se consultan ni se cobran). La lista está en `2 · Consulta directa por fuente`.\n\nVERSIÓN DEL BANCO: 2026-09-04.1. Dos corridas con la misma versión dan el mismo resultado.","event":[{"listen":"prerequest","script":{"type":"text/javascript","exec":["// El sandbox necesita una key de PRUEBA (`vf_test_…`): con una de","// producción estos documentos sintéticos irían a los portales reales y se","// cobrarían créditos. Sin key de prueba, el request NO sale.","var claveDePrueba = pm.variables.replaceIn(\"{{api_key_test}}\") || \"\";","if (claveDePrueba.indexOf(\"vf_test_\") !== 0) {","    pm.request.headers.upsert({ key: \"X-API-KEY\", value: \"\" });","    console.warn(\"Pegá tu API key de PRUEBA (vf_test_...) en la variable `api_key_test`. Este request no se mandó.\");","    if (pm.execution && pm.execution.skipRequest) {","        pm.execution.skipRequest();","    }","}"]}}]},{"name":"1 · Reporte unificado (empezá acá)","item":[{"name":"Estimar costo (gratis)","request":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/reports/estimate","host":["{{base_url}}"],"path":["api","v1","gateway","api","reports","estimate"]},"description":"Qué fuentes aplican y cuántos créditos cuesta. No cobra y no consulta nada — es la forma más barata de saber qué vas a recibir.\n\n`omitted_sources` es lo más útil de la respuesta: dice, ANTES de gastar, qué campo falta para incluir cada fuente que quedó fuera. Una con `reason: \"degraded\"` no falta nada: su portal está caído, no se consulta y no se cobra. Una degradada puede volver cuando el portal se restablezca; una RETIRADA (hoy, la DIAN) queda sin fecha de vuelta: su `hint` lo dice.\n\nTipos de documento aceptados: CC, CE, NIT, PA. OJO: el reporte acepta MENOS tipos que la consulta directa por fuente —que admite hasta CC, CE, NIT, PA, PPT y TI según la fuente—. Un tipo fuera de este conjunto NO omite una fuente: rechaza el reporte entero.","body":{"mode":"raw","raw":"{\n  \"tipo_documento\": \"CC\",\n  \"numero_documento\": \"900000003\",\n  \"data_authorization_declared\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Estimar costo (gratis) — ejemplo","originalRequest":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/reports/estimate","host":["{{base_url}}"],"path":["api","v1","gateway","api","reports","estimate"]},"description":"Qué fuentes aplican y cuántos créditos cuesta. No cobra y no consulta nada — es la forma más barata de saber qué vas a recibir.\n\n`omitted_sources` es lo más útil de la respuesta: dice, ANTES de gastar, qué campo falta para incluir cada fuente que quedó fuera. Una con `reason: \"degraded\"` no falta nada: su portal está caído, no se consulta y no se cobra. Una degradada puede volver cuando el portal se restablezca; una RETIRADA (hoy, la DIAN) queda sin fecha de vuelta: su `hint` lo dice.\n\nTipos de documento aceptados: CC, CE, NIT, PA. OJO: el reporte acepta MENOS tipos que la consulta directa por fuente —que admite hasta CC, CE, NIT, PA, PPT y TI según la fuente—. Un tipo fuera de este conjunto NO omite una fuente: rechaza el reporte entero.","body":{"mode":"raw","raw":"{\n  \"tipo_documento\": \"CC\",\n  \"numero_documento\": \"900000003\",\n  \"data_authorization_declared\": true\n}","options":{"raw":{"language":"json"}}}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"total_credits\": 14,\n  \"sources\": [\n    {\n      \"provider\": \"verifycol\",\n      \"endpoint\": \"ofac-search\",\n      \"endpoint_name\": \"Lista Clinton (OFAC/SDN)\",\n      \"category\": \"ofac\",\n      \"credit_cost\": 1\n    },\n    {\n      \"provider\": \"verifycol\",\n      \"endpoint\": \"procuraduria-ordinario\",\n      \"endpoint_name\": \"Procuraduría — antecedentes ordinarios\",\n      \"category\": \"procuraduria\",\n      \"credit_cost\": 1\n    }\n  ],\n  \"omitted_sources\": [\n    {\n      \"endpoint\": \"simit-consultar\",\n      \"endpoint_name\": \"SIMIT\",\n      \"category\": \"simit\",\n      \"reason\": \"missing_required_field\",\n      \"missing_fields\": [\n        \"filtro\"\n      ],\n      \"hint\": \"Mandá `extra_fields.filtro` con la placa o el documento.\"\n    }\n  ],\n  \"available_credits\": 4986,\n  \"can_proceed\": true,\n  \"blockers\": []\n}"}],"event":[{"listen":"test","script":{"type":"text/javascript","exec":["pm.test(\"El estimate responde 200 con fuentes, omitidas y can_proceed\", function () {","    pm.response.to.have.status(200);","    var b = pm.response.json();","    pm.expect(b.sources).to.be.an(\"array\");","    pm.expect(b.omitted_sources, \"lo que queda fuera y por qué\").to.be.an(\"array\");","    pm.expect(b.can_proceed).to.be.a(\"boolean\");","});"]}}]},{"name":"Crear reporte","request":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"Idempotency-Key","value":"{{$guid}}","type":"text","description":"Identifica ESTA solicitud. Un reintento por timeout de red con la misma clave devuelve el reporte original —con el header `Idempotent-Replayed: true`— en vez de crear y cobrar otro. Ventana: 24 h. `{{$guid}}` genera una clave nueva en cada envío, que es lo correcto para una solicitud nueva."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/reports/","host":["{{base_url}}"],"path":["api","v1","gateway","api","reports"]},"description":"Consulta todas las fuentes aplicables y arma el reporte. Responde **201** con el `id` (no `report_id`) y cobra al aceptar.\n\nPuede responder **202** en vez de 201 si tu organización exige el consentimiento del titular: ahí NO hay reporte ni cobro todavía. Programá los dos códigos — ver `5 · Consentimiento del titular`.\n\n**410 `GONE`** si reintentás con la MISMA `Idempotency-Key` y el reporte original fue suprimido a solicitud del titular (Ley 1581): no se crea ni se cobra uno nuevo. No reintentes.\n\nManda `Idempotency-Key: {{$guid}}`: si tu reintento por timeout de red lleva la MISMA clave, recibís el reporte original con `Idempotent-Replayed: true` y no se cobra dos veces. Con esa clave puesta NO se aplica el dedup de 30 s: la clave pasa a ser la identidad del pedido, así que dos claves distintas son dos verificaciones y se cobran las dos. Ver la carpeta `4 · Certificación de idempotencia`.\n\nEL DOCUMENTO DEL EJEMPLO (900000003) es un sujeto sintético del banco del sandbox: con una key de prueba (`vf_test_`) en `api_key` responde limpio, gratis. Con una key live (`vf_live_`) la consulta va a las fuentes reales y SE COBRA: reemplazalo por el de un titular que te autorizó.\n\nTipos de documento aceptados: CC, CE, NIT, PA. OJO: el reporte acepta MENOS tipos que la consulta directa por fuente —que admite hasta CC, CE, NIT, PA, PPT y TI según la fuente—. Un tipo fuera de este conjunto NO omite una fuente: rechaza el reporte entero.","body":{"mode":"raw","raw":"{\n  \"tipo_documento\": \"CC\",\n  \"numero_documento\": \"900000003\",\n  \"data_authorization_declared\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Crear reporte — ejemplo","originalRequest":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"Idempotency-Key","value":"{{$guid}}","type":"text","description":"Identifica ESTA solicitud. Un reintento por timeout de red con la misma clave devuelve el reporte original —con el header `Idempotent-Replayed: true`— en vez de crear y cobrar otro. Ventana: 24 h. `{{$guid}}` genera una clave nueva en cada envío, que es lo correcto para una solicitud nueva."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/reports/","host":["{{base_url}}"],"path":["api","v1","gateway","api","reports"]},"description":"Consulta todas las fuentes aplicables y arma el reporte. Responde **201** con el `id` (no `report_id`) y cobra al aceptar.\n\nPuede responder **202** en vez de 201 si tu organización exige el consentimiento del titular: ahí NO hay reporte ni cobro todavía. Programá los dos códigos — ver `5 · Consentimiento del titular`.\n\n**410 `GONE`** si reintentás con la MISMA `Idempotency-Key` y el reporte original fue suprimido a solicitud del titular (Ley 1581): no se crea ni se cobra uno nuevo. No reintentes.\n\nManda `Idempotency-Key: {{$guid}}`: si tu reintento por timeout de red lleva la MISMA clave, recibís el reporte original con `Idempotent-Replayed: true` y no se cobra dos veces. Con esa clave puesta NO se aplica el dedup de 30 s: la clave pasa a ser la identidad del pedido, así que dos claves distintas son dos verificaciones y se cobran las dos. Ver la carpeta `4 · Certificación de idempotencia`.\n\nEL DOCUMENTO DEL EJEMPLO (900000003) es un sujeto sintético del banco del sandbox: con una key de prueba (`vf_test_`) en `api_key` responde limpio, gratis. Con una key live (`vf_live_`) la consulta va a las fuentes reales y SE COBRA: reemplazalo por el de un titular que te autorizó.\n\nTipos de documento aceptados: CC, CE, NIT, PA. OJO: el reporte acepta MENOS tipos que la consulta directa por fuente —que admite hasta CC, CE, NIT, PA, PPT y TI según la fuente—. Un tipo fuera de este conjunto NO omite una fuente: rechaza el reporte entero.","body":{"mode":"raw","raw":"{\n  \"tipo_documento\": \"CC\",\n  \"numero_documento\": \"900000003\",\n  \"data_authorization_declared\": true\n}","options":{"raw":{"language":"json"}}}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": \"3f2a8c10-5b7e-4d21-9a44-1c8e6b0d5f93\",\n  \"status\": \"processing\",\n  \"overall_status\": null,\n  \"subject_document_type\": \"CC\",\n  \"subject_document_number\": \"900000003\",\n  \"subject_full_name\": null,\n  \"total_sources\": 14,\n  \"completed_sources\": 0,\n  \"successful_sources\": 0,\n  \"failed_sources\": 0,\n  \"sources\": [],\n  \"total_credits_charged\": 14,\n  \"credits_reserved\": 14,\n  \"credits_refunded\": 0,\n  \"omitted_sources\": [],\n  \"omitted_sources_count\": 0,\n  \"has_pdf\": false,\n  \"pdf_generated_at\": null,\n  \"created_at\": \"2026-09-02T14:05:11Z\",\n  \"completed_at\": null,\n  \"deduplicated\": false,\n  \"origin\": null,\n  \"environment\": \"live\",\n  \"test_mode\": false,\n  \"external_reference\": null,\n  \"correlation_id\": null,\n  \"informational_only\": false,\n  \"informational_sources\": 0,\n  \"conclusive_sources\": 0,\n  \"coverage_sufficient\": false,\n  \"covered_dimensions\": [],\n  \"uncovered_dimensions\": [],\n  \"uncovered_coverage_groups\": [],\n  \"narrative_status\": \"none\",\n  \"risk_analysis\": null,\n  \"risk_narrative\": null,\n  \"narrative_generated_at\": null\n}"}],"event":[{"listen":"test","script":{"type":"text/javascript","exec":["pm.test(\"201 con el reporte (o 202 si tu organización exige el consentimiento del titular)\", function () {","    pm.expect([201, 202]).to.include(pm.response.code);","    var b = pm.response.json();","    if (pm.response.code === 201) {","        pm.expect(b.id, \"el identificador es `id`, no `report_id`\").to.be.a(\"string\");","        // Para Consultar, el PDF, los soportes y la conciliación.","        pm.collectionVariables.set(\"report_id\", b.id);","    } else {","        pm.expect(b.consent_id).to.be.a(\"string\");","        pm.collectionVariables.set(\"consent_id\", b.consent_id);","    }","});"]}}]},{"name":"Consultar reporte","request":{"method":"GET","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/reports/{{report_id}}","host":["{{base_url}}"],"path":["api","v1","gateway","api","reports","{{report_id}}"]},"description":"Estado y resultado. Poné `report_id` en las variables de la colección.\n\nEstados terminales: `completed`, `partial`, `failed`. **`partial` NO es un error**: alguna fuente no respondió, sus créditos se reembolsaron solos y el resto del reporte es válido. Si tu integración trata `completed` como única condición de éxito, se va a romper sin que nada esté mal.\n\n`credits_reserved - credits_refunded` es lo cobrado neto, y es el número que tiene que cuadrar con el libro (`6 · Créditos y conciliación`).\n\n`has_pdf` dice si el PDF YA se generó alguna vez —la marca la pone la descarga—, no si se puede pedir: en un reporte `completed` o `partial` el PDF se pide igual con `has_pdf: false`."},"response":[{"name":"Consultar reporte — ejemplo","originalRequest":{"method":"GET","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/reports/{{report_id}}","host":["{{base_url}}"],"path":["api","v1","gateway","api","reports","{{report_id}}"]},"description":"Estado y resultado. Poné `report_id` en las variables de la colección.\n\nEstados terminales: `completed`, `partial`, `failed`. **`partial` NO es un error**: alguna fuente no respondió, sus créditos se reembolsaron solos y el resto del reporte es válido. Si tu integración trata `completed` como única condición de éxito, se va a romper sin que nada esté mal.\n\n`credits_reserved - credits_refunded` es lo cobrado neto, y es el número que tiene que cuadrar con el libro (`6 · Créditos y conciliación`).\n\n`has_pdf` dice si el PDF YA se generó alguna vez —la marca la pone la descarga—, no si se puede pedir: en un reporte `completed` o `partial` el PDF se pide igual con `has_pdf: false`."},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": \"3f2a8c10-5b7e-4d21-9a44-1c8e6b0d5f93\",\n  \"status\": \"partial\",\n  \"overall_status\": \"warning\",\n  \"subject_document_type\": \"CC\",\n  \"subject_document_number\": \"900000003\",\n  \"subject_full_name\": \"SUJETO DE PRUEBA VERIFYCOL\",\n  \"total_sources\": 14,\n  \"completed_sources\": 13,\n  \"successful_sources\": 13,\n  \"failed_sources\": 1,\n  \"sources\": [\n    {\n      \"provider\": \"verifycol\",\n      \"endpoint\": \"ofac-search\",\n      \"endpoint_name\": \"Lista Clinton (OFAC/SDN)\",\n      \"category\": \"ofac\",\n      \"task_id\": null,\n      \"status\": \"completed\",\n      \"is_clean\": true,\n      \"status_message\": \"Sin coincidencias\",\n      \"subject_name\": null,\n      \"data\": null,\n      \"error\": null,\n      \"response_time_ms\": null,\n      \"error_code\": null,\n      \"retryable\": null,\n      \"undetermined\": null,\n      \"informational\": null,\n      \"credits_charged\": 1,\n      \"credits_refunded\": null,\n      \"anexo_estado\": null,\n      \"soportes\": null,\n      \"data_warning\": null,\n      \"last_verified\": null,\n      \"source_updated_at\": null,\n      \"started_at\": null,\n      \"completed_at\": null\n    },\n    {\n      \"provider\": \"verifycol\",\n      \"endpoint\": \"dian-rut-estado\",\n      \"endpoint_name\": \"DIAN — estado del RUT\",\n      \"category\": \"fiscal\",\n      \"task_id\": null,\n      \"status\": \"failed\",\n      \"is_clean\": null,\n      \"status_message\": null,\n      \"subject_name\": null,\n      \"data\": null,\n      \"error\": \"La fuente no respondió a tiempo\",\n      \"response_time_ms\": null,\n      \"error_code\": \"provider_error\",\n      \"retryable\": true,\n      \"undetermined\": null,\n      \"informational\": null,\n      \"credits_charged\": 0,\n      \"credits_refunded\": 1,\n      \"anexo_estado\": null,\n      \"soportes\": null,\n      \"data_warning\": null,\n      \"last_verified\": null,\n      \"source_updated_at\": null,\n      \"started_at\": null,\n      \"completed_at\": null\n    }\n  ],\n  \"total_credits_charged\": 13,\n  \"credits_reserved\": 14,\n  \"credits_refunded\": 1,\n  \"omitted_sources\": [\n    {\n      \"endpoint\": \"runt-persona-consultar\",\n      \"endpoint_name\": \"RUNT — persona\",\n      \"category\": \"transito\",\n      \"reason\": \"degraded\",\n      \"missing_fields\": [],\n      \"hint\": \"Fuente suspendida: no se consultó ni se cobró. Puede volver cuando el portal se restablezca.\",\n      \"available_from_plan\": null\n    }\n  ],\n  \"omitted_sources_count\": 1,\n  \"has_pdf\": false,\n  \"pdf_generated_at\": null,\n  \"created_at\": \"2026-09-02T14:05:11Z\",\n  \"completed_at\": \"2026-09-02T14:07:36Z\",\n  \"deduplicated\": false,\n  \"origin\": null,\n  \"environment\": \"live\",\n  \"test_mode\": false,\n  \"external_reference\": null,\n  \"correlation_id\": \"mi-traza-9f3c\",\n  \"informational_only\": false,\n  \"informational_sources\": 0,\n  \"conclusive_sources\": 0,\n  \"coverage_sufficient\": false,\n  \"covered_dimensions\": [],\n  \"uncovered_dimensions\": [],\n  \"uncovered_coverage_groups\": [],\n  \"narrative_status\": \"none\",\n  \"risk_analysis\": null,\n  \"risk_narrative\": null,\n  \"narrative_generated_at\": null\n}"}],"event":[{"listen":"prerequest","script":{"type":"text/javascript","exec":["if (!pm.variables.get(\"report_id\")) {","    console.warn(\"Falta la variable `report_id`: este request no se mandó.\");","    pm.execution.skipRequest();","}"]}},{"listen":"test","script":{"type":"text/javascript","exec":["pm.test(\"El reporte responde 200 con su estado\", function () {","    pm.response.to.have.status(200);","    var b = pm.response.json();","    pm.expect(b.id).to.eql(pm.variables.get(\"report_id\"));","    pm.expect(b.status).to.be.oneOf([\"pending\", \"processing\", \"completed\", \"partial\", \"failed\"]);","    pm.expect(b.sources).to.be.an(\"array\");","});"]}}]},{"name":"Descargar PDF","request":{"method":"GET","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/reports/{{report_id}}/pdf","host":["{{base_url}}"],"path":["api","v1","gateway","api","reports","{{report_id}}","pdf"]},"description":"El PDF firmado del reporte. Devuelve `application/pdf`, no JSON."},"event":[{"listen":"prerequest","script":{"type":"text/javascript","exec":["if (!pm.variables.get(\"report_id\")) {","    console.warn(\"Falta la variable `report_id`: este request no se mandó.\");","    pm.execution.skipRequest();","}"]}},{"listen":"test","script":{"type":"text/javascript","exec":["pm.test(\"El PDF responde 200 (o 422 si el reporte no cerró todavía)\", function () {","    pm.expect([200, 422]).to.include(pm.response.code);","    if (pm.response.code === 200) {","        var tipo = pm.response.headers.get(\"Content-Type\") || \"\";","        pm.expect(tipo, \"esta ruta devuelve un PDF, no JSON\").to.include(\"application/pdf\");","    }","});"]}}]},{"name":"Descargar los soportes de una fuente","request":{"method":"GET","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/reports/{{report_id}}/fuentes/{{indice}}/soportes","host":["{{base_url}}"],"path":["api","v1","gateway","api","reports","{{report_id}}","fuentes","{{indice}}","soportes"]},"description":"Los documentos de soporte de la fuente `indice` (su posición en `sources`, desde 0) en un solo PDF; si hay uno solo, ese mismo. Devuelve `application/pdf`, no JSON. Se piden al crear el reporte con `soportes: \"descargables\"` o `\"anexos\"`, y `sources[].soportes` los describe.\n\n`404` si la fuente no tiene soportes o no están disponibles. Si hay dos o más que no se pudieron unir, el `404` trae `error.reason: SOPORTES_NO_UNIDOS`: bajalos uno por uno.\n\nSi la copia todavía se está descargando, la ruta intenta completarla en el momento (hasta ~20 s); si no alcanza, responde `404` con `Retry-After: 30`. `410` si el reporte fue suprimido a solicitud del titular (Ley 1581)."},"event":[{"listen":"prerequest","script":{"type":"text/javascript","exec":["if (!pm.variables.get(\"report_id\")) {","    console.warn(\"Falta la variable `report_id`: este request no se mandó.\");","    pm.execution.skipRequest();","}"]}},{"listen":"test","script":{"type":"text/javascript","exec":["pm.test(\"Los soportes responden 200 con un PDF, o 404/410\", function () {","    pm.expect([200, 404, 410]).to.include(pm.response.code);","    if (pm.response.code === 200) {","        var tipo = pm.response.headers.get(\"Content-Type\") || \"\";","        pm.expect(tipo, \"esta ruta devuelve un PDF, no JSON\").to.include(\"application/pdf\");","    }","});"]}}]},{"name":"Descargar un soporte de una fuente","request":{"method":"GET","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/reports/{{report_id}}/fuentes/{{indice}}/soportes/{{j}}","host":["{{base_url}}"],"path":["api","v1","gateway","api","reports","{{report_id}}","fuentes","{{indice}}","soportes","{{j}}"]},"description":"El soporte `j` (su posición en `sources[indice].soportes`, desde 0), tal como se copió: su `sha256` está en esa entrada del reporte. Devuelve `application/pdf`, no JSON. `404` si no está disponible.\n\nSi la copia todavía se está descargando, la ruta intenta completarla en el momento (hasta ~20 s); si no alcanza, responde `404` con `Retry-After: 30`. `410` si el reporte fue suprimido a solicitud del titular (Ley 1581)."},"event":[{"listen":"prerequest","script":{"type":"text/javascript","exec":["if (!pm.variables.get(\"report_id\")) {","    console.warn(\"Falta la variable `report_id`: este request no se mandó.\");","    pm.execution.skipRequest();","}"]}},{"listen":"test","script":{"type":"text/javascript","exec":["pm.test(\"El soporte responde 200 con un PDF, o 404/410\", function () {","    pm.expect([200, 404, 410]).to.include(pm.response.code);","    if (pm.response.code === 200) {","        var tipo = pm.response.headers.get(\"Content-Type\") || \"\";","        pm.expect(tipo, \"esta ruta devuelve un PDF, no JSON\").to.include(\"application/pdf\");","    }","});"]}}]},{"name":"Listar reportes","request":{"method":"GET","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/reports/?page=1&page_size=20","host":["{{base_url}}"],"path":["api","v1","gateway","api","reports"],"query":[{"key":"page","value":"1"},{"key":"page_size","value":"20"}]},"description":"Los reportes de tu organización, del más reciente al más viejo. Paginado con `page` y `page_size`; la respuesta trae `pages` (cantidad de páginas), no `page_size`.\n\nExiste para recuperar un `report_id` ya COBRADO que se perdió: un timeout leyendo la respuesta, o una creación sin `Idempotency-Key`."},"response":[{"name":"Listar reportes — ejemplo","originalRequest":{"method":"GET","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/reports/?page=1&page_size=20","host":["{{base_url}}"],"path":["api","v1","gateway","api","reports"],"query":[{"key":"page","value":"1"},{"key":"page_size","value":"20"}]},"description":"Los reportes de tu organización, del más reciente al más viejo. Paginado con `page` y `page_size`; la respuesta trae `pages` (cantidad de páginas), no `page_size`.\n\nExiste para recuperar un `report_id` ya COBRADO que se perdió: un timeout leyendo la respuesta, o una creación sin `Idempotency-Key`."},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"items\": [\n    {\n      \"id\": \"3f2a8c10-5b7e-4d21-9a44-1c8e6b0d5f93\",\n      \"status\": \"partial\",\n      \"overall_status\": \"warning\",\n      \"subject_document_type\": \"CC\",\n      \"subject_document_number\": \"900000003\",\n      \"subject_full_name\": \"SUJETO DE PRUEBA VERIFYCOL\",\n      \"total_sources\": 14,\n      \"successful_sources\": 13,\n      \"failed_sources\": 1,\n      \"total_credits_charged\": 13,\n      \"has_pdf\": false,\n      \"created_at\": \"2026-09-02T14:05:11Z\",\n      \"completed_at\": \"2026-09-02T14:07:36Z\",\n      \"origin\": \"full\",\n      \"external_reference\": null,\n      \"informational_only\": false,\n      \"coverage_sufficient\": false,\n      \"narrative_status\": null,\n      \"environment\": \"live\"\n    }\n  ],\n  \"total\": 1,\n  \"page\": 1,\n  \"pages\": 1\n}"}],"event":[{"listen":"test","script":{"type":"text/javascript","exec":["pm.test(\"El listado responde 200, paginado\", function () {","    pm.response.to.have.status(200);","    var b = pm.response.json();","    pm.expect(b.items).to.be.an(\"array\");","    pm.expect(b.pages, \"trae `pages`, no `page_size`\").to.be.a(\"number\");","});"]}}]}],"description":"El camino recomendado: UNA llamada consulta todas las fuentes que aplican al sujeto y devuelve un reporte con su PDF."},{"name":"2 · Consulta directa por fuente","item":[{"name":"Listas restrictivas","item":[{"name":"Australia DFAT","request":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"X-Data-Authorization","value":"true","type":"text","description":"Ley 1581: declarás que contás con la autorización del titular para consultar sus datos. Es una declaración TUYA y queda registrada como evidencia. Sin este header la consulta se rechaza con 400 y no se cobra."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/services/verifycol/australia-dfat-search","host":["{{base_url}}"],"path":["api","v1","gateway","services","verifycol","australia-dfat-search"]},"description":"Australia — sanciones (DFAT) (Gobierno de Australia). Sanciones de Australia. Puede dar hallazgo.\n\nCosto: 1 crédito(s).\n\nRequiere el header `X-Data-Authorization: true` — Ley 1581. Es una declaración TUYA de que contás con la autorización del titular, y queda registrada como evidencia. Sin ella: 400, y no se cobra.\n\nEN EL SANDBOX (key `vf_test_`): el documento del ejemplo (900000008) es un sujeto del banco y responde su escenario, gratis. Con una key live va a la fuente real y se cobra: reemplazalo por el de un titular que te autorizó.","body":{"mode":"raw","raw":"{\n  \"query\": \"EMPRESA DE PRUEBA VERIFYCOL S.A.S.\",\n  \"document_number\": \"900000008\",\n  \"subject_type\": \"all\",\n  \"subject_nationality\": \"COLOMBIA\",\n  \"min_score\": 75,\n  \"max_results\": 25\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Australia DFAT — ejemplo","originalRequest":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"X-Data-Authorization","value":"true","type":"text","description":"Ley 1581: declarás que contás con la autorización del titular para consultar sus datos. Es una declaración TUYA y queda registrada como evidencia. Sin este header la consulta se rechaza con 400 y no se cobra."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/services/verifycol/australia-dfat-search","host":["{{base_url}}"],"path":["api","v1","gateway","services","verifycol","australia-dfat-search"]},"description":"Australia — sanciones (DFAT) (Gobierno de Australia). Sanciones de Australia. Puede dar hallazgo.\n\nCosto: 1 crédito(s).\n\nRequiere el header `X-Data-Authorization: true` — Ley 1581. Es una declaración TUYA de que contás con la autorización del titular, y queda registrada como evidencia. Sin ella: 400, y no se cobra.\n\nEN EL SANDBOX (key `vf_test_`): el documento del ejemplo (900000008) es un sujeto del banco y responde su escenario, gratis. Con una key live va a la fuente real y se cobra: reemplazalo por el de un titular que te autorizó.","body":{"mode":"raw","raw":"{\n  \"query\": \"EMPRESA DE PRUEBA VERIFYCOL S.A.S.\",\n  \"document_number\": \"900000008\",\n  \"subject_type\": \"all\",\n  \"subject_nationality\": \"COLOMBIA\",\n  \"min_score\": 75,\n  \"max_results\": 25\n}","options":{"raw":{"language":"json"}}}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"status_code\": 200,\n  \"credits_charged\": 1,\n  \"credits_remaining\": 4999,\n  \"request_id\": \"3f2a8c10-5b7e-4d21-9a44-1c8e6b0d5f93\",\n  \"data\": {\n    \"query\": \"JUAN PEREZ GOMEZ\",\n    \"match_status\": \"no_match\",\n    \"is_match\": false,\n    \"highest_score\": 0.0,\n    \"total_matches\": 0,\n    \"results\": [],\n    \"last_sync\": \"2026-08-26T01:50:19Z\",\n    \"consulted_at\": \"2026-08-26T04:15:22Z\",\n    \"source_code\": \"australia_dfat\",\n    \"source_url\": \"https://www.dfat.gov.au/sites/default/files/Australian_Sanctions_Consolidated_List.xlsx\",\n    \"data_warning\": null,\n    \"schema_version\": 1\n  }\n}"}],"event":[{"listen":"test","script":{"type":"text/javascript","exec":["var sinCaso = pm.response.code === 400 &&","    pm.response.text().indexOf(\"sandbox_sin_caso\") >= 0;","if (sinCaso) {","    console.log(\"El sandbox no tiene escenario para esta fuente con este documento (sandbox_sin_caso): no se evaluó.\");","}","var t = sinCaso ? pm.test.skip : pm.test;","","t(\"La consulta responde 200/202 con el sobre del proxy\", function () {","    pm.expect([200, 202]).to.include(pm.response.code);","    var b = pm.response.json();","    pm.expect(b.success, \"success:false con status 2xx no debería pasar\").to.be.true;","    pm.expect(b).to.have.property(\"data\");","});"]}}]},{"name":"Banco Mundial — Firmas e Individuos Inhabilitados","request":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"X-Data-Authorization","value":"true","type":"text","description":"Ley 1581: declarás que contás con la autorización del titular para consultar sus datos. Es una declaración TUYA y queda registrada como evidencia. Sin este header la consulta se rechaza con 400 y no se cobra."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/services/verifycol/worldbank-debarred-search","host":["{{base_url}}"],"path":["api","v1","gateway","services","verifycol","worldbank-debarred-search"]},"description":"Banco Mundial — inhabilitados (Banco Mundial). Firmas e individuos inhabilitados para contratar con el Banco Mundial. Puede dar hallazgo.\n\nCosto: 1 crédito(s).\n\nRequiere el header `X-Data-Authorization: true` — Ley 1581. Es una declaración TUYA de que contás con la autorización del titular, y queda registrada como evidencia. Sin ella: 400, y no se cobra.\n\nEN EL SANDBOX (key `vf_test_`): el documento del ejemplo (900000008) es un sujeto del banco y responde su escenario, gratis. Con una key live va a la fuente real y se cobra: reemplazalo por el de un titular que te autorizó.","body":{"mode":"raw","raw":"{\n  \"query\": \"EMPRESA DE PRUEBA VERIFYCOL S.A.S.\",\n  \"document_number\": \"900000008\",\n  \"subject_type\": \"all\",\n  \"subject_nationality\": \"COLOMBIA\",\n  \"min_score\": 75,\n  \"max_results\": 25\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Banco Mundial — Firmas e Individuos Inhabilitados — ejemplo","originalRequest":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"X-Data-Authorization","value":"true","type":"text","description":"Ley 1581: declarás que contás con la autorización del titular para consultar sus datos. Es una declaración TUYA y queda registrada como evidencia. Sin este header la consulta se rechaza con 400 y no se cobra."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/services/verifycol/worldbank-debarred-search","host":["{{base_url}}"],"path":["api","v1","gateway","services","verifycol","worldbank-debarred-search"]},"description":"Banco Mundial — inhabilitados (Banco Mundial). Firmas e individuos inhabilitados para contratar con el Banco Mundial. Puede dar hallazgo.\n\nCosto: 1 crédito(s).\n\nRequiere el header `X-Data-Authorization: true` — Ley 1581. Es una declaración TUYA de que contás con la autorización del titular, y queda registrada como evidencia. Sin ella: 400, y no se cobra.\n\nEN EL SANDBOX (key `vf_test_`): el documento del ejemplo (900000008) es un sujeto del banco y responde su escenario, gratis. Con una key live va a la fuente real y se cobra: reemplazalo por el de un titular que te autorizó.","body":{"mode":"raw","raw":"{\n  \"query\": \"EMPRESA DE PRUEBA VERIFYCOL S.A.S.\",\n  \"document_number\": \"900000008\",\n  \"subject_type\": \"all\",\n  \"subject_nationality\": \"COLOMBIA\",\n  \"min_score\": 75,\n  \"max_results\": 25\n}","options":{"raw":{"language":"json"}}}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"status_code\": 200,\n  \"credits_charged\": 1,\n  \"credits_remaining\": 4999,\n  \"request_id\": \"3f2a8c10-5b7e-4d21-9a44-1c8e6b0d5f93\",\n  \"data\": {\n    \"query\": \"JUAN PEREZ GOMEZ\",\n    \"match_status\": \"no_match\",\n    \"is_match\": false,\n    \"highest_score\": 0.0,\n    \"total_matches\": 0,\n    \"results\": [],\n    \"last_sync\": \"2026-08-26T01:50:19Z\",\n    \"consulted_at\": \"2026-08-26T04:15:22Z\",\n    \"source_code\": \"worldbank\",\n    \"source_url\": \"https://www.worldbank.org/en/projects-operations/procurement/debarred-firms\",\n    \"data_warning\": null,\n    \"schema_version\": 1\n  }\n}"}],"event":[{"listen":"test","script":{"type":"text/javascript","exec":["var sinCaso = pm.response.code === 400 &&","    pm.response.text().indexOf(\"sandbox_sin_caso\") >= 0;","if (sinCaso) {","    console.log(\"El sandbox no tiene escenario para esta fuente con este documento (sandbox_sin_caso): no se evaluó.\");","}","var t = sinCaso ? pm.test.skip : pm.test;","","t(\"La consulta responde 200/202 con el sobre del proxy\", function () {","    pm.expect([200, 202]).to.include(pm.response.code);","    var b = pm.response.json();","    pm.expect(b.success, \"success:false con status 2xx no debería pasar\").to.be.true;","    pm.expect(b).to.have.property(\"data\");","});"]}}]},{"name":"Canadá OSFI/SEMA","request":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"X-Data-Authorization","value":"true","type":"text","description":"Ley 1581: declarás que contás con la autorización del titular para consultar sus datos. Es una declaración TUYA y queda registrada como evidencia. Sin este header la consulta se rechaza con 400 y no se cobra."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/services/verifycol/canada-osfi-search","host":["{{base_url}}"],"path":["api","v1","gateway","services","verifycol","canada-osfi-search"]},"description":"Canadá — sanciones (OSFI/SEMA) (Gobierno de Canadá). Sanciones de Canadá. Puede dar hallazgo.\n\nCosto: 1 crédito(s).\n\nRequiere el header `X-Data-Authorization: true` — Ley 1581. Es una declaración TUYA de que contás con la autorización del titular, y queda registrada como evidencia. Sin ella: 400, y no se cobra.\n\nEN EL SANDBOX (key `vf_test_`): el documento del ejemplo (900000008) es un sujeto del banco y responde su escenario, gratis. Con una key live va a la fuente real y se cobra: reemplazalo por el de un titular que te autorizó.","body":{"mode":"raw","raw":"{\n  \"query\": \"EMPRESA DE PRUEBA VERIFYCOL S.A.S.\",\n  \"document_number\": \"900000008\",\n  \"subject_type\": \"all\",\n  \"subject_nationality\": \"COLOMBIA\",\n  \"min_score\": 75,\n  \"max_results\": 25\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Canadá OSFI/SEMA — ejemplo","originalRequest":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"X-Data-Authorization","value":"true","type":"text","description":"Ley 1581: declarás que contás con la autorización del titular para consultar sus datos. Es una declaración TUYA y queda registrada como evidencia. Sin este header la consulta se rechaza con 400 y no se cobra."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/services/verifycol/canada-osfi-search","host":["{{base_url}}"],"path":["api","v1","gateway","services","verifycol","canada-osfi-search"]},"description":"Canadá — sanciones (OSFI/SEMA) (Gobierno de Canadá). Sanciones de Canadá. Puede dar hallazgo.\n\nCosto: 1 crédito(s).\n\nRequiere el header `X-Data-Authorization: true` — Ley 1581. Es una declaración TUYA de que contás con la autorización del titular, y queda registrada como evidencia. Sin ella: 400, y no se cobra.\n\nEN EL SANDBOX (key `vf_test_`): el documento del ejemplo (900000008) es un sujeto del banco y responde su escenario, gratis. Con una key live va a la fuente real y se cobra: reemplazalo por el de un titular que te autorizó.","body":{"mode":"raw","raw":"{\n  \"query\": \"EMPRESA DE PRUEBA VERIFYCOL S.A.S.\",\n  \"document_number\": \"900000008\",\n  \"subject_type\": \"all\",\n  \"subject_nationality\": \"COLOMBIA\",\n  \"min_score\": 75,\n  \"max_results\": 25\n}","options":{"raw":{"language":"json"}}}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"status_code\": 200,\n  \"credits_charged\": 1,\n  \"credits_remaining\": 4999,\n  \"request_id\": \"3f2a8c10-5b7e-4d21-9a44-1c8e6b0d5f93\",\n  \"data\": {\n    \"query\": \"JUAN PEREZ GOMEZ\",\n    \"match_status\": \"no_match\",\n    \"is_match\": false,\n    \"highest_score\": 0.0,\n    \"total_matches\": 0,\n    \"results\": [],\n    \"last_sync\": \"2026-08-26T01:50:19Z\",\n    \"consulted_at\": \"2026-08-26T04:15:22Z\",\n    \"source_code\": \"canada_osfi\",\n    \"source_url\": \"https://www.international.gc.ca/world-monde/assets/office_docs/international_relations-relations_internationales/sanctions/sema-lmes.xml\",\n    \"data_warning\": null,\n    \"schema_version\": 1\n  }\n}"}],"event":[{"listen":"test","script":{"type":"text/javascript","exec":["var sinCaso = pm.response.code === 400 &&","    pm.response.text().indexOf(\"sandbox_sin_caso\") >= 0;","if (sinCaso) {","    console.log(\"El sandbox no tiene escenario para esta fuente con este documento (sandbox_sin_caso): no se evaluó.\");","}","var t = sinCaso ? pm.test.skip : pm.test;","","t(\"La consulta responde 200/202 con el sobre del proxy\", function () {","    pm.expect([200, 202]).to.include(pm.response.code);","    var b = pm.response.json();","    pm.expect(b.success, \"success:false con status 2xx no debería pasar\").to.be.true;","    pm.expect(b).to.have.property(\"data\");","});"]}}]},{"name":"INTERPOL — Red Notices","request":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"X-Data-Authorization","value":"true","type":"text","description":"Ley 1581: declarás que contás con la autorización del titular para consultar sus datos. Es una declaración TUYA y queda registrada como evidencia. Sin este header la consulta se rechaza con 400 y no se cobra."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/services/verifycol/interpol-search","host":["{{base_url}}"],"path":["api","v1","gateway","services","verifycol","interpol-search"]},"description":"INTERPOL — notificaciones rojas (INTERPOL). Personas buscadas con notificación roja. Puede dar hallazgo.\n\nCosto: 1 crédito(s).\n\nRequiere el header `X-Data-Authorization: true` — Ley 1581. Es una declaración TUYA de que contás con la autorización del titular, y queda registrada como evidencia. Sin ella: 400, y no se cobra.\n\nEN EL SANDBOX (key `vf_test_`): el documento del ejemplo (900000008) es un sujeto del banco y responde su escenario, gratis. Con una key live va a la fuente real y se cobra: reemplazalo por el de un titular que te autorizó.","body":{"mode":"raw","raw":"{\n  \"query\": \"EMPRESA DE PRUEBA VERIFYCOL S.A.S.\",\n  \"document_number\": \"900000008\",\n  \"subject_type\": \"all\",\n  \"subject_nationality\": \"COLOMBIA\",\n  \"min_score\": 75,\n  \"max_results\": 25\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"INTERPOL — Red Notices — ejemplo","originalRequest":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"X-Data-Authorization","value":"true","type":"text","description":"Ley 1581: declarás que contás con la autorización del titular para consultar sus datos. Es una declaración TUYA y queda registrada como evidencia. Sin este header la consulta se rechaza con 400 y no se cobra."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/services/verifycol/interpol-search","host":["{{base_url}}"],"path":["api","v1","gateway","services","verifycol","interpol-search"]},"description":"INTERPOL — notificaciones rojas (INTERPOL). Personas buscadas con notificación roja. Puede dar hallazgo.\n\nCosto: 1 crédito(s).\n\nRequiere el header `X-Data-Authorization: true` — Ley 1581. Es una declaración TUYA de que contás con la autorización del titular, y queda registrada como evidencia. Sin ella: 400, y no se cobra.\n\nEN EL SANDBOX (key `vf_test_`): el documento del ejemplo (900000008) es un sujeto del banco y responde su escenario, gratis. Con una key live va a la fuente real y se cobra: reemplazalo por el de un titular que te autorizó.","body":{"mode":"raw","raw":"{\n  \"query\": \"EMPRESA DE PRUEBA VERIFYCOL S.A.S.\",\n  \"document_number\": \"900000008\",\n  \"subject_type\": \"all\",\n  \"subject_nationality\": \"COLOMBIA\",\n  \"min_score\": 75,\n  \"max_results\": 25\n}","options":{"raw":{"language":"json"}}}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"status_code\": 200,\n  \"credits_charged\": 1,\n  \"credits_remaining\": 4999,\n  \"request_id\": \"3f2a8c10-5b7e-4d21-9a44-1c8e6b0d5f93\",\n  \"data\": {\n    \"query\": \"JUAN PEREZ GOMEZ\",\n    \"match_status\": \"no_match\",\n    \"is_match\": false,\n    \"highest_score\": 0.0,\n    \"total_matches\": 0,\n    \"results\": [],\n    \"last_sync\": \"2026-08-26T01:50:19Z\",\n    \"consulted_at\": \"2026-08-26T04:15:22Z\",\n    \"source_code\": \"interpol\",\n    \"source_url\": \"https://ws-public.interpol.int/notices/v1/red\",\n    \"data_warning\": null,\n    \"schema_version\": 1\n  }\n}"}],"event":[{"listen":"test","script":{"type":"text/javascript","exec":["var sinCaso = pm.response.code === 400 &&","    pm.response.text().indexOf(\"sandbox_sin_caso\") >= 0;","if (sinCaso) {","    console.log(\"El sandbox no tiene escenario para esta fuente con este documento (sandbox_sin_caso): no se evaluó.\");","}","var t = sinCaso ? pm.test.skip : pm.test;","","t(\"La consulta responde 200/202 con el sobre del proxy\", function () {","    pm.expect([200, 202]).to.include(pm.response.code);","    var b = pm.response.json();","    pm.expect(b.success, \"success:false con status 2xx no debería pasar\").to.be.true;","    pm.expect(b).to.have.property(\"data\");","});"]}}]},{"name":"Lista Clinton (OFAC/SDN)","request":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"X-Data-Authorization","value":"true","type":"text","description":"Ley 1581: declarás que contás con la autorización del titular para consultar sus datos. Es una declaración TUYA y queda registrada como evidencia. Sin este header la consulta se rechaza con 400 y no se cobra."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/services/verifycol/ofac-search","host":["{{base_url}}"],"path":["api","v1","gateway","services","verifycol","ofac-search"]},"description":"Lista Clinton (OFAC — SDN) (Departamento del Tesoro de EE. UU.). Sanciones del Tesoro de EE. UU. Puede dar hallazgo.\n\nCosto: 1 crédito(s).\n\nRequiere el header `X-Data-Authorization: true` — Ley 1581. Es una declaración TUYA de que contás con la autorización del titular, y queda registrada como evidencia. Sin ella: 400, y no se cobra.\n\nEN EL SANDBOX (key `vf_test_`): el documento del ejemplo (900000008) es un sujeto del banco y responde su escenario, gratis. Con una key live va a la fuente real y se cobra: reemplazalo por el de un titular que te autorizó.","body":{"mode":"raw","raw":"{\n  \"query\": \"EMPRESA DE PRUEBA VERIFYCOL S.A.S.\",\n  \"document_number\": \"900000008\",\n  \"type\": \"all\",\n  \"country\": \"all\",\n  \"program\": \"all\",\n  \"min_score\": 75,\n  \"max_results\": 25\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Lista Clinton (OFAC/SDN) — ejemplo","originalRequest":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"X-Data-Authorization","value":"true","type":"text","description":"Ley 1581: declarás que contás con la autorización del titular para consultar sus datos. Es una declaración TUYA y queda registrada como evidencia. Sin este header la consulta se rechaza con 400 y no se cobra."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/services/verifycol/ofac-search","host":["{{base_url}}"],"path":["api","v1","gateway","services","verifycol","ofac-search"]},"description":"Lista Clinton (OFAC — SDN) (Departamento del Tesoro de EE. UU.). Sanciones del Tesoro de EE. UU. Puede dar hallazgo.\n\nCosto: 1 crédito(s).\n\nRequiere el header `X-Data-Authorization: true` — Ley 1581. Es una declaración TUYA de que contás con la autorización del titular, y queda registrada como evidencia. Sin ella: 400, y no se cobra.\n\nEN EL SANDBOX (key `vf_test_`): el documento del ejemplo (900000008) es un sujeto del banco y responde su escenario, gratis. Con una key live va a la fuente real y se cobra: reemplazalo por el de un titular que te autorizó.","body":{"mode":"raw","raw":"{\n  \"query\": \"EMPRESA DE PRUEBA VERIFYCOL S.A.S.\",\n  \"document_number\": \"900000008\",\n  \"type\": \"all\",\n  \"country\": \"all\",\n  \"program\": \"all\",\n  \"min_score\": 75,\n  \"max_results\": 25\n}","options":{"raw":{"language":"json"}}}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"status_code\": 200,\n  \"credits_charged\": 1,\n  \"credits_remaining\": 4999,\n  \"request_id\": \"3f2a8c10-5b7e-4d21-9a44-1c8e6b0d5f93\",\n  \"data\": {\n    \"query\": \"JUAN PEREZ GOMEZ\",\n    \"match_status\": \"no_match\",\n    \"is_match\": false,\n    \"highest_score\": 0.0,\n    \"total_matches\": 0,\n    \"results\": [],\n    \"last_sync\": \"2026-08-26T01:50:19Z\",\n    \"consulted_at\": \"2026-08-26T04:15:22Z\",\n    \"source_code\": \"ofac\",\n    \"source_url\": \"https://www.treasury.gov/ofac/downloads/consolidated/consolidated.xml\",\n    \"data_warning\": null,\n    \"disclaimer\": \"Esta consulta es una herramienta de asistencia para debida diligencia. Los resultados deben ser verificados por un oficial de cumplimiento. Una ausencia de coincidencias NO constituye certificación legal de que el consultado no se encuentra en listas restrictivas. Fuente: U.S. Department of the Treasury - OFAC.\",\n    \"schema_version\": 1\n  }\n}"}],"event":[{"listen":"test","script":{"type":"text/javascript","exec":["var sinCaso = pm.response.code === 400 &&","    pm.response.text().indexOf(\"sandbox_sin_caso\") >= 0;","if (sinCaso) {","    console.log(\"El sandbox no tiene escenario para esta fuente con este documento (sandbox_sin_caso): no se evaluó.\");","}","var t = sinCaso ? pm.test.skip : pm.test;","","t(\"La consulta responde 200/202 con el sobre del proxy\", function () {","    pm.expect([200, 202]).to.include(pm.response.code);","    var b = pm.response.json();","    pm.expect(b.success, \"success:false con status 2xx no debería pasar\").to.be.true;","    pm.expect(b).to.have.property(\"data\");","});"]}}]},{"name":"Lista ONU — Consejo de Seguridad","request":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"X-Data-Authorization","value":"true","type":"text","description":"Ley 1581: declarás que contás con la autorización del titular para consultar sus datos. Es una declaración TUYA y queda registrada como evidencia. Sin este header la consulta se rechaza con 400 y no se cobra."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/services/verifycol/onu-search","host":["{{base_url}}"],"path":["api","v1","gateway","services","verifycol","onu-search"]},"description":"Lista del Consejo de Seguridad (Naciones Unidas). Lista consolidada de sanciones, vinculante en Colombia (Ley 1121 de 2006). Puede dar hallazgo.\n\nCosto: 1 crédito(s).\n\nRequiere el header `X-Data-Authorization: true` — Ley 1581. Es una declaración TUYA de que contás con la autorización del titular, y queda registrada como evidencia. Sin ella: 400, y no se cobra.\n\nEN EL SANDBOX (key `vf_test_`): el documento del ejemplo (900000008) es un sujeto del banco y responde su escenario, gratis. Con una key live va a la fuente real y se cobra: reemplazalo por el de un titular que te autorizó.","body":{"mode":"raw","raw":"{\n  \"query\": \"EMPRESA DE PRUEBA VERIFYCOL S.A.S.\",\n  \"document_number\": \"900000008\",\n  \"type\": \"all\",\n  \"regime\": \"all\",\n  \"country\": \"all\",\n  \"min_score\": 75,\n  \"max_results\": 25\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Lista ONU — Consejo de Seguridad — ejemplo","originalRequest":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"X-Data-Authorization","value":"true","type":"text","description":"Ley 1581: declarás que contás con la autorización del titular para consultar sus datos. Es una declaración TUYA y queda registrada como evidencia. Sin este header la consulta se rechaza con 400 y no se cobra."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/services/verifycol/onu-search","host":["{{base_url}}"],"path":["api","v1","gateway","services","verifycol","onu-search"]},"description":"Lista del Consejo de Seguridad (Naciones Unidas). Lista consolidada de sanciones, vinculante en Colombia (Ley 1121 de 2006). Puede dar hallazgo.\n\nCosto: 1 crédito(s).\n\nRequiere el header `X-Data-Authorization: true` — Ley 1581. Es una declaración TUYA de que contás con la autorización del titular, y queda registrada como evidencia. Sin ella: 400, y no se cobra.\n\nEN EL SANDBOX (key `vf_test_`): el documento del ejemplo (900000008) es un sujeto del banco y responde su escenario, gratis. Con una key live va a la fuente real y se cobra: reemplazalo por el de un titular que te autorizó.","body":{"mode":"raw","raw":"{\n  \"query\": \"EMPRESA DE PRUEBA VERIFYCOL S.A.S.\",\n  \"document_number\": \"900000008\",\n  \"type\": \"all\",\n  \"regime\": \"all\",\n  \"country\": \"all\",\n  \"min_score\": 75,\n  \"max_results\": 25\n}","options":{"raw":{"language":"json"}}}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"status_code\": 200,\n  \"credits_charged\": 1,\n  \"credits_remaining\": 4999,\n  \"request_id\": \"3f2a8c10-5b7e-4d21-9a44-1c8e6b0d5f93\",\n  \"data\": {\n    \"query\": \"JUAN PEREZ GOMEZ\",\n    \"match_status\": \"no_match\",\n    \"is_match\": false,\n    \"highest_score\": 0.0,\n    \"total_matches\": 0,\n    \"results\": [],\n    \"last_sync\": \"2026-08-26T01:50:19Z\",\n    \"consulted_at\": \"2026-08-26T04:15:22Z\",\n    \"source_code\": \"onu\",\n    \"source_url\": \"https://scsanctions.un.org/resources/xml/en/consolidated.xml\",\n    \"data_warning\": null,\n    \"disclaimer\": \"Esta consulta es una herramienta de asistencia para debida diligencia SARLAFT/SAGRILAFT. Los resultados deben ser verificados por un oficial de cumplimiento. Una ausencia de coincidencias NO constituye certificación legal de que el consultado no se encuentra en listas restrictivas. LISTA VINCULANTE para Colombia (Ley 1121 de 2006, Art. 20). Fuente: Consejo de Seguridad de las Naciones Unidas.\",\n    \"schema_version\": 1\n  }\n}"}],"event":[{"listen":"test","script":{"type":"text/javascript","exec":["var sinCaso = pm.response.code === 400 &&","    pm.response.text().indexOf(\"sandbox_sin_caso\") >= 0;","if (sinCaso) {","    console.log(\"El sandbox no tiene escenario para esta fuente con este documento (sandbox_sin_caso): no se evaluó.\");","}","var t = sinCaso ? pm.test.skip : pm.test;","","t(\"La consulta responde 200/202 con el sobre del proxy\", function () {","    pm.expect([200, 202]).to.include(pm.response.code);","    var b = pm.response.json();","    pm.expect(b.success, \"success:false con status 2xx no debería pasar\").to.be.true;","    pm.expect(b).to.have.property(\"data\");","});"]}}]},{"name":"PEP Colombia — SIGEP II","request":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"X-Data-Authorization","value":"true","type":"text","description":"Ley 1581: declarás que contás con la autorización del titular para consultar sus datos. Es una declaración TUYA y queda registrada como evidencia. Sin este header la consulta se rechaza con 400 y no se cobra."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/services/verifycol/pep-search","host":["{{base_url}}"],"path":["api","v1","gateway","services","verifycol","pep-search"]},"description":"PEP Colombia (Función Pública (SIGEP II)). Personas expuestas políticamente (Decreto 830 de 2021). Puede dar hallazgo.\n\nCosto: 1 crédito(s).\n\nRequiere el header `X-Data-Authorization: true` — Ley 1581. Es una declaración TUYA de que contás con la autorización del titular, y queda registrada como evidencia. Sin ella: 400, y no se cobra.\n\nEN EL SANDBOX (key `vf_test_`): el documento del ejemplo (900000003) es un sujeto del banco y responde su escenario, gratis. Con una key live va a la fuente real y se cobra: reemplazalo por el de un titular que te autorizó.","body":{"mode":"raw","raw":"{\n  \"query\": \"SUJETO DE PRUEBA VERIFYCOL\",\n  \"document_number\": \"900000003\",\n  \"min_score\": 75,\n  \"max_results\": 25,\n  \"include_ex_pep\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"PEP Colombia — SIGEP II — ejemplo","originalRequest":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"X-Data-Authorization","value":"true","type":"text","description":"Ley 1581: declarás que contás con la autorización del titular para consultar sus datos. Es una declaración TUYA y queda registrada como evidencia. Sin este header la consulta se rechaza con 400 y no se cobra."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/services/verifycol/pep-search","host":["{{base_url}}"],"path":["api","v1","gateway","services","verifycol","pep-search"]},"description":"PEP Colombia (Función Pública (SIGEP II)). Personas expuestas políticamente (Decreto 830 de 2021). Puede dar hallazgo.\n\nCosto: 1 crédito(s).\n\nRequiere el header `X-Data-Authorization: true` — Ley 1581. Es una declaración TUYA de que contás con la autorización del titular, y queda registrada como evidencia. Sin ella: 400, y no se cobra.\n\nEN EL SANDBOX (key `vf_test_`): el documento del ejemplo (900000003) es un sujeto del banco y responde su escenario, gratis. Con una key live va a la fuente real y se cobra: reemplazalo por el de un titular que te autorizó.","body":{"mode":"raw","raw":"{\n  \"query\": \"SUJETO DE PRUEBA VERIFYCOL\",\n  \"document_number\": \"900000003\",\n  \"min_score\": 75,\n  \"max_results\": 25,\n  \"include_ex_pep\": true\n}","options":{"raw":{"language":"json"}}}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"status_code\": 200,\n  \"credits_charged\": 1,\n  \"credits_remaining\": 4999,\n  \"request_id\": \"3f2a8c10-5b7e-4d21-9a44-1c8e6b0d5f93\",\n  \"data\": {\n    \"query\": \"JUAN PEREZ GOMEZ\",\n    \"match_status\": \"no_match\",\n    \"is_match\": false,\n    \"highest_score\": 0.0,\n    \"total_matches\": 0,\n    \"results\": [],\n    \"last_sync\": \"2026-08-26T01:50:19Z\",\n    \"consulted_at\": \"2026-08-26T04:15:22Z\",\n    \"source_code\": \"pep\",\n    \"source_url\": \"https://www.funcionpublica.gov.co/fdci/consultaCiudadana/consultaPEP\",\n    \"data_warning\": null,\n    \"disclaimer\": \"Esta consulta es una herramienta de asistencia para debida diligencia SARLAFT/SAGRILAFT (Decreto 830 de 2021, Circular Básica Jurídica Título IV Cap. IV). Los resultados deben ser verificados por un oficial de cumplimiento. IMPORTANTE: La base de datos SIGEP II tiene un subregistro estimado del 25-30%. La ausencia de coincidencias NO certifica que la persona consultada no sea PEP. Esta consulta NO incluye PEP extranjeras ni familiares/asociados cercanos de PEP. Fuentes: Función Pública — lista PEP oficial de SIGEP (primaria, en vivo) unida al histórico del dataset 3qxn-uc22 de datos.gov.co. Los hallazgos marcados 'solo_historico' figuran únicamente en el histórico y la fuente oficial no los lista hoy.\",\n    \"schema_version\": 1\n  }\n}"}],"event":[{"listen":"test","script":{"type":"text/javascript","exec":["var sinCaso = pm.response.code === 400 &&","    pm.response.text().indexOf(\"sandbox_sin_caso\") >= 0;","if (sinCaso) {","    console.log(\"El sandbox no tiene escenario para esta fuente con este documento (sandbox_sin_caso): no se evaluó.\");","}","var t = sinCaso ? pm.test.skip : pm.test;","","t(\"La consulta responde 200/202 con el sobre del proxy\", function () {","    pm.expect([200, 202]).to.include(pm.response.code);","    var b = pm.response.json();","    pm.expect(b.success, \"success:false con status 2xx no debería pasar\").to.be.true;","    pm.expect(b).to.have.property(\"data\");","});"]}}]},{"name":"Reino Unido — UK Sanctions List (FCDO)","request":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"X-Data-Authorization","value":"true","type":"text","description":"Ley 1581: declarás que contás con la autorización del titular para consultar sus datos. Es una declaración TUYA y queda registrada como evidencia. Sin este header la consulta se rechaza con 400 y no se cobra."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/services/verifycol/uk-ofsi-search","host":["{{base_url}}"],"path":["api","v1","gateway","services","verifycol","uk-ofsi-search"]},"description":"Reino Unido — UK Sanctions List (Gobierno del Reino Unido (FCDO)). Sanciones del Reino Unido. Puede dar hallazgo.\n\nCosto: 1 crédito(s).\n\nRequiere el header `X-Data-Authorization: true` — Ley 1581. Es una declaración TUYA de que contás con la autorización del titular, y queda registrada como evidencia. Sin ella: 400, y no se cobra.\n\nEN EL SANDBOX (key `vf_test_`): el documento del ejemplo (900000008) es un sujeto del banco y responde su escenario, gratis. Con una key live va a la fuente real y se cobra: reemplazalo por el de un titular que te autorizó.","body":{"mode":"raw","raw":"{\n  \"query\": \"EMPRESA DE PRUEBA VERIFYCOL S.A.S.\",\n  \"document_number\": \"900000008\",\n  \"subject_type\": \"all\",\n  \"subject_nationality\": \"COLOMBIA\",\n  \"min_score\": 75,\n  \"max_results\": 25\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Reino Unido — UK Sanctions List (FCDO) — ejemplo","originalRequest":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"X-Data-Authorization","value":"true","type":"text","description":"Ley 1581: declarás que contás con la autorización del titular para consultar sus datos. Es una declaración TUYA y queda registrada como evidencia. Sin este header la consulta se rechaza con 400 y no se cobra."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/services/verifycol/uk-ofsi-search","host":["{{base_url}}"],"path":["api","v1","gateway","services","verifycol","uk-ofsi-search"]},"description":"Reino Unido — UK Sanctions List (Gobierno del Reino Unido (FCDO)). Sanciones del Reino Unido. Puede dar hallazgo.\n\nCosto: 1 crédito(s).\n\nRequiere el header `X-Data-Authorization: true` — Ley 1581. Es una declaración TUYA de que contás con la autorización del titular, y queda registrada como evidencia. Sin ella: 400, y no se cobra.\n\nEN EL SANDBOX (key `vf_test_`): el documento del ejemplo (900000008) es un sujeto del banco y responde su escenario, gratis. Con una key live va a la fuente real y se cobra: reemplazalo por el de un titular que te autorizó.","body":{"mode":"raw","raw":"{\n  \"query\": \"EMPRESA DE PRUEBA VERIFYCOL S.A.S.\",\n  \"document_number\": \"900000008\",\n  \"subject_type\": \"all\",\n  \"subject_nationality\": \"COLOMBIA\",\n  \"min_score\": 75,\n  \"max_results\": 25\n}","options":{"raw":{"language":"json"}}}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"status_code\": 200,\n  \"credits_charged\": 1,\n  \"credits_remaining\": 4999,\n  \"request_id\": \"3f2a8c10-5b7e-4d21-9a44-1c8e6b0d5f93\",\n  \"data\": {\n    \"query\": \"JUAN PEREZ GOMEZ\",\n    \"match_status\": \"no_match\",\n    \"is_match\": false,\n    \"highest_score\": 0.0,\n    \"total_matches\": 0,\n    \"results\": [],\n    \"last_sync\": \"2026-08-26T01:50:19Z\",\n    \"consulted_at\": \"2026-08-26T04:15:22Z\",\n    \"source_code\": \"uk_ofsi\",\n    \"source_url\": \"https://sanctionslist.fcdo.gov.uk/docs/UK-Sanctions-List.csv\",\n    \"data_warning\": null,\n    \"schema_version\": 1\n  }\n}"}],"event":[{"listen":"test","script":{"type":"text/javascript","exec":["var sinCaso = pm.response.code === 400 &&","    pm.response.text().indexOf(\"sandbox_sin_caso\") >= 0;","if (sinCaso) {","    console.log(\"El sandbox no tiene escenario para esta fuente con este documento (sandbox_sin_caso): no se evaluó.\");","}","var t = sinCaso ? pm.test.skip : pm.test;","","t(\"La consulta responde 200/202 con el sobre del proxy\", function () {","    pm.expect([200, 202]).to.include(pm.response.code);","    var b = pm.response.json();","    pm.expect(b.success, \"success:false con status 2xx no debería pasar\").to.be.true;","    pm.expect(b).to.have.property(\"data\");","});"]}}]},{"name":"Suiza SECO","request":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"X-Data-Authorization","value":"true","type":"text","description":"Ley 1581: declarás que contás con la autorización del titular para consultar sus datos. Es una declaración TUYA y queda registrada como evidencia. Sin este header la consulta se rechaza con 400 y no se cobra."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/services/verifycol/swiss-seco-search","host":["{{base_url}}"],"path":["api","v1","gateway","services","verifycol","swiss-seco-search"]},"description":"Suiza — sanciones (SECO) (Gobierno de Suiza). Sanciones de Suiza. Puede dar hallazgo.\n\nCosto: 1 crédito(s).\n\nRequiere el header `X-Data-Authorization: true` — Ley 1581. Es una declaración TUYA de que contás con la autorización del titular, y queda registrada como evidencia. Sin ella: 400, y no se cobra.\n\nEN EL SANDBOX (key `vf_test_`): el documento del ejemplo (900000008) es un sujeto del banco y responde su escenario, gratis. Con una key live va a la fuente real y se cobra: reemplazalo por el de un titular que te autorizó.","body":{"mode":"raw","raw":"{\n  \"query\": \"EMPRESA DE PRUEBA VERIFYCOL S.A.S.\",\n  \"document_number\": \"900000008\",\n  \"subject_type\": \"all\",\n  \"subject_nationality\": \"COLOMBIA\",\n  \"min_score\": 75,\n  \"max_results\": 25\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Suiza SECO — ejemplo","originalRequest":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"X-Data-Authorization","value":"true","type":"text","description":"Ley 1581: declarás que contás con la autorización del titular para consultar sus datos. Es una declaración TUYA y queda registrada como evidencia. Sin este header la consulta se rechaza con 400 y no se cobra."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/services/verifycol/swiss-seco-search","host":["{{base_url}}"],"path":["api","v1","gateway","services","verifycol","swiss-seco-search"]},"description":"Suiza — sanciones (SECO) (Gobierno de Suiza). Sanciones de Suiza. Puede dar hallazgo.\n\nCosto: 1 crédito(s).\n\nRequiere el header `X-Data-Authorization: true` — Ley 1581. Es una declaración TUYA de que contás con la autorización del titular, y queda registrada como evidencia. Sin ella: 400, y no se cobra.\n\nEN EL SANDBOX (key `vf_test_`): el documento del ejemplo (900000008) es un sujeto del banco y responde su escenario, gratis. Con una key live va a la fuente real y se cobra: reemplazalo por el de un titular que te autorizó.","body":{"mode":"raw","raw":"{\n  \"query\": \"EMPRESA DE PRUEBA VERIFYCOL S.A.S.\",\n  \"document_number\": \"900000008\",\n  \"subject_type\": \"all\",\n  \"subject_nationality\": \"COLOMBIA\",\n  \"min_score\": 75,\n  \"max_results\": 25\n}","options":{"raw":{"language":"json"}}}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"status_code\": 200,\n  \"credits_charged\": 1,\n  \"credits_remaining\": 4999,\n  \"request_id\": \"3f2a8c10-5b7e-4d21-9a44-1c8e6b0d5f93\",\n  \"data\": {\n    \"query\": \"JUAN PEREZ GOMEZ\",\n    \"match_status\": \"no_match\",\n    \"is_match\": false,\n    \"highest_score\": 0.0,\n    \"total_matches\": 0,\n    \"results\": [],\n    \"last_sync\": \"2026-08-26T01:50:19Z\",\n    \"consulted_at\": \"2026-08-26T04:15:22Z\",\n    \"source_code\": \"swiss_seco\",\n    \"source_url\": \"https://www.sesam.search.admin.ch/sesam-search-web/pages/downloadXmlGesamtliste.xhtml?lang=de&action=downloadXmlGesamtlisteAction\",\n    \"data_warning\": null,\n    \"schema_version\": 1\n  }\n}"}],"event":[{"listen":"test","script":{"type":"text/javascript","exec":["var sinCaso = pm.response.code === 400 &&","    pm.response.text().indexOf(\"sandbox_sin_caso\") >= 0;","if (sinCaso) {","    console.log(\"El sandbox no tiene escenario para esta fuente con este documento (sandbox_sin_caso): no se evaluó.\");","}","var t = sinCaso ? pm.test.skip : pm.test;","","t(\"La consulta responde 200/202 con el sobre del proxy\", function () {","    pm.expect([200, 202]).to.include(pm.response.code);","    var b = pm.response.json();","    pm.expect(b.success, \"success:false con status 2xx no debería pasar\").to.be.true;","    pm.expect(b).to.have.property(\"data\");","});"]}}]},{"name":"Unión Europea — Sanciones (CFSP)","request":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"X-Data-Authorization","value":"true","type":"text","description":"Ley 1581: declarás que contás con la autorización del titular para consultar sus datos. Es una declaración TUYA y queda registrada como evidencia. Sin este header la consulta se rechaza con 400 y no se cobra."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/services/verifycol/eu-sanctions-search","host":["{{base_url}}"],"path":["api","v1","gateway","services","verifycol","eu-sanctions-search"]},"description":"Unión Europea — sanciones (CFSP) (Unión Europea). Sanciones de la Unión Europea. Puede dar hallazgo.\n\nCosto: 1 crédito(s).\n\nRequiere el header `X-Data-Authorization: true` — Ley 1581. Es una declaración TUYA de que contás con la autorización del titular, y queda registrada como evidencia. Sin ella: 400, y no se cobra.\n\nEN EL SANDBOX (key `vf_test_`): el documento del ejemplo (900000008) es un sujeto del banco y responde su escenario, gratis. Con una key live va a la fuente real y se cobra: reemplazalo por el de un titular que te autorizó.","body":{"mode":"raw","raw":"{\n  \"query\": \"EMPRESA DE PRUEBA VERIFYCOL S.A.S.\",\n  \"document_number\": \"900000008\",\n  \"subject_type\": \"all\",\n  \"subject_nationality\": \"COLOMBIA\",\n  \"min_score\": 75,\n  \"max_results\": 25\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Unión Europea — Sanciones (CFSP) — ejemplo","originalRequest":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"X-Data-Authorization","value":"true","type":"text","description":"Ley 1581: declarás que contás con la autorización del titular para consultar sus datos. Es una declaración TUYA y queda registrada como evidencia. Sin este header la consulta se rechaza con 400 y no se cobra."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/services/verifycol/eu-sanctions-search","host":["{{base_url}}"],"path":["api","v1","gateway","services","verifycol","eu-sanctions-search"]},"description":"Unión Europea — sanciones (CFSP) (Unión Europea). Sanciones de la Unión Europea. Puede dar hallazgo.\n\nCosto: 1 crédito(s).\n\nRequiere el header `X-Data-Authorization: true` — Ley 1581. Es una declaración TUYA de que contás con la autorización del titular, y queda registrada como evidencia. Sin ella: 400, y no se cobra.\n\nEN EL SANDBOX (key `vf_test_`): el documento del ejemplo (900000008) es un sujeto del banco y responde su escenario, gratis. Con una key live va a la fuente real y se cobra: reemplazalo por el de un titular que te autorizó.","body":{"mode":"raw","raw":"{\n  \"query\": \"EMPRESA DE PRUEBA VERIFYCOL S.A.S.\",\n  \"document_number\": \"900000008\",\n  \"subject_type\": \"all\",\n  \"subject_nationality\": \"COLOMBIA\",\n  \"min_score\": 75,\n  \"max_results\": 25\n}","options":{"raw":{"language":"json"}}}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"status_code\": 200,\n  \"credits_charged\": 1,\n  \"credits_remaining\": 4999,\n  \"request_id\": \"3f2a8c10-5b7e-4d21-9a44-1c8e6b0d5f93\",\n  \"data\": {\n    \"query\": \"JUAN PEREZ GOMEZ\",\n    \"match_status\": \"no_match\",\n    \"is_match\": false,\n    \"highest_score\": 0.0,\n    \"total_matches\": 0,\n    \"results\": [],\n    \"last_sync\": \"2026-08-26T01:50:19Z\",\n    \"consulted_at\": \"2026-08-26T04:15:22Z\",\n    \"source_code\": \"eu_sanctions\",\n    \"source_url\": \"https://webgate.ec.europa.eu/fsd/fsf/public/files/xmlFullSanctionsList_1_1/content\",\n    \"data_warning\": null,\n    \"schema_version\": 1\n  }\n}"}],"event":[{"listen":"test","script":{"type":"text/javascript","exec":["var sinCaso = pm.response.code === 400 &&","    pm.response.text().indexOf(\"sandbox_sin_caso\") >= 0;","if (sinCaso) {","    console.log(\"El sandbox no tiene escenario para esta fuente con este documento (sandbox_sin_caso): no se evaluó.\");","}","var t = sinCaso ? pm.test.skip : pm.test;","","t(\"La consulta responde 200/202 con el sobre del proxy\", function () {","    pm.expect([200, 202]).to.include(pm.response.code);","    var b = pm.response.json();","    pm.expect(b.success, \"success:false con status 2xx no debería pasar\").to.be.true;","    pm.expect(b).to.have.property(\"data\");","});"]}}]}]},{"name":"Antecedentes y sanciones","item":[{"name":"Contraloría - Persona Jurídica","request":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"X-Data-Authorization","value":"true","type":"text","description":"Ley 1581: declarás que contás con la autorización del titular para consultar sus datos. Es una declaración TUYA y queda registrada como evidencia. Sin este header la consulta se rechaza con 400 y no se cobra."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/services/verifycol/contraloria-juridica","host":["{{base_url}}"],"path":["api","v1","gateway","services","verifycol","contraloria-juridica"]},"description":"Contraloría — persona jurídica (Contraloría General de la República). Responsabilidad fiscal de la empresa. Puede dar hallazgo.\n\nCosto: 1 crédito(s).\n\nASÍNCRONO: responde 202 con `task_id` y `status: \"QUEUED\"` (en MAYÚSCULAS). El resultado se recoge sondeando `/api/v1/gateway/services/verifycol/tasks/{task_id}` cada 2-5 s hasta `COMPLETED` o `FAILED`.\n\nRequiere el header `X-Data-Authorization: true` — Ley 1581. Es una declaración TUYA de que contás con la autorización del titular, y queda registrada como evidencia. Sin ella: 400, y no se cobra.\n\nEN EL SANDBOX (key `vf_test_`): el documento del ejemplo (900000008) es un sujeto del banco y responde su escenario, gratis. Con una key live va a la fuente real y se cobra: reemplazalo por el de un titular que te autorizó.","body":{"mode":"raw","raw":"{\n  \"documents\": [\n    {\n      \"nit\": \"900000008\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Contraloría - Persona Jurídica — ejemplo","originalRequest":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"X-Data-Authorization","value":"true","type":"text","description":"Ley 1581: declarás que contás con la autorización del titular para consultar sus datos. Es una declaración TUYA y queda registrada como evidencia. Sin este header la consulta se rechaza con 400 y no se cobra."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/services/verifycol/contraloria-juridica","host":["{{base_url}}"],"path":["api","v1","gateway","services","verifycol","contraloria-juridica"]},"description":"Contraloría — persona jurídica (Contraloría General de la República). Responsabilidad fiscal de la empresa. Puede dar hallazgo.\n\nCosto: 1 crédito(s).\n\nASÍNCRONO: responde 202 con `task_id` y `status: \"QUEUED\"` (en MAYÚSCULAS). El resultado se recoge sondeando `/api/v1/gateway/services/verifycol/tasks/{task_id}` cada 2-5 s hasta `COMPLETED` o `FAILED`.\n\nRequiere el header `X-Data-Authorization: true` — Ley 1581. Es una declaración TUYA de que contás con la autorización del titular, y queda registrada como evidencia. Sin ella: 400, y no se cobra.\n\nEN EL SANDBOX (key `vf_test_`): el documento del ejemplo (900000008) es un sujeto del banco y responde su escenario, gratis. Con una key live va a la fuente real y se cobra: reemplazalo por el de un titular que te autorizó.","body":{"mode":"raw","raw":"{\n  \"documents\": [\n    {\n      \"nit\": \"900000008\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"status":"Accepted","code":202,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"task_id\": \"abc-124\",\n  \"status\": \"QUEUED\",\n  \"total\": 1,\n  \"type\": \"juridica\",\n  \"message\": \"Tarea creada exitosamente\"\n}"}],"event":[{"listen":"test","script":{"type":"text/javascript","exec":["var sinCaso = pm.response.code === 400 &&","    pm.response.text().indexOf(\"sandbox_sin_caso\") >= 0;","if (sinCaso) {","    console.log(\"El sandbox no tiene escenario para esta fuente con este documento (sandbox_sin_caso): no se evaluó.\");","}","var t = sinCaso ? pm.test.skip : pm.test;","","t(\"La consulta responde 200/202 con el sobre del proxy\", function () {","    pm.expect([200, 202]).to.include(pm.response.code);","    var b = pm.response.json();","    pm.expect(b.success, \"success:false con status 2xx no debería pasar\").to.be.true;","    pm.expect(b).to.have.property(\"data\");","    var tarea = b.data && b.data.task_id;","    pm.expect(tarea, \"sin data.task_id no hay qué sondear\").to.be.a(\"string\");","    // Para `3 · Tareas → Estado y resultado de UNA tarea`.","    pm.collectionVariables.set(\"task_id\", tarea);","});"]}}]},{"name":"Contraloría - Persona Natural","request":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"X-Data-Authorization","value":"true","type":"text","description":"Ley 1581: declarás que contás con la autorización del titular para consultar sus datos. Es una declaración TUYA y queda registrada como evidencia. Sin este header la consulta se rechaza con 400 y no se cobra."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/services/verifycol/contraloria-natural","host":["{{base_url}}"],"path":["api","v1","gateway","services","verifycol","contraloria-natural"]},"description":"Contraloría — persona natural (Contraloría General de la República). Responsabilidad fiscal. Puede dar hallazgo.\n\nCosto: 1 crédito(s).\n\nTipos de documento aceptados: CC, CE, TI, PA, PPT. Cualquier otro se rechaza con 422 y NO cobra créditos.\n\nASÍNCRONO: responde 202 con `task_id` y `status: \"QUEUED\"` (en MAYÚSCULAS). El resultado se recoge sondeando `/api/v1/gateway/services/verifycol/tasks/{task_id}` cada 2-5 s hasta `COMPLETED` o `FAILED`.\n\nRequiere el header `X-Data-Authorization: true` — Ley 1581. Es una declaración TUYA de que contás con la autorización del titular, y queda registrada como evidencia. Sin ella: 400, y no se cobra.\n\nEN EL SANDBOX (key `vf_test_`): el documento del ejemplo (900000003) es un sujeto del banco y responde su escenario, gratis. Con una key live va a la fuente real y se cobra: reemplazalo por el de un titular que te autorizó.","body":{"mode":"raw","raw":"{\n  \"documents\": [\n    {\n      \"tipo_documento\": \"CC\",\n      \"numero_documento\": \"900000003\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Contraloría - Persona Natural — ejemplo","originalRequest":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"X-Data-Authorization","value":"true","type":"text","description":"Ley 1581: declarás que contás con la autorización del titular para consultar sus datos. Es una declaración TUYA y queda registrada como evidencia. Sin este header la consulta se rechaza con 400 y no se cobra."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/services/verifycol/contraloria-natural","host":["{{base_url}}"],"path":["api","v1","gateway","services","verifycol","contraloria-natural"]},"description":"Contraloría — persona natural (Contraloría General de la República). Responsabilidad fiscal. Puede dar hallazgo.\n\nCosto: 1 crédito(s).\n\nTipos de documento aceptados: CC, CE, TI, PA, PPT. Cualquier otro se rechaza con 422 y NO cobra créditos.\n\nASÍNCRONO: responde 202 con `task_id` y `status: \"QUEUED\"` (en MAYÚSCULAS). El resultado se recoge sondeando `/api/v1/gateway/services/verifycol/tasks/{task_id}` cada 2-5 s hasta `COMPLETED` o `FAILED`.\n\nRequiere el header `X-Data-Authorization: true` — Ley 1581. Es una declaración TUYA de que contás con la autorización del titular, y queda registrada como evidencia. Sin ella: 400, y no se cobra.\n\nEN EL SANDBOX (key `vf_test_`): el documento del ejemplo (900000003) es un sujeto del banco y responde su escenario, gratis. Con una key live va a la fuente real y se cobra: reemplazalo por el de un titular que te autorizó.","body":{"mode":"raw","raw":"{\n  \"documents\": [\n    {\n      \"tipo_documento\": \"CC\",\n      \"numero_documento\": \"900000003\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"status":"Accepted","code":202,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"task_id\": \"abc-123\",\n  \"status\": \"QUEUED\",\n  \"total\": 1,\n  \"type\": \"natural\",\n  \"message\": \"Tarea creada exitosamente\"\n}"}],"event":[{"listen":"test","script":{"type":"text/javascript","exec":["var sinCaso = pm.response.code === 400 &&","    pm.response.text().indexOf(\"sandbox_sin_caso\") >= 0;","if (sinCaso) {","    console.log(\"El sandbox no tiene escenario para esta fuente con este documento (sandbox_sin_caso): no se evaluó.\");","}","var t = sinCaso ? pm.test.skip : pm.test;","","t(\"La consulta responde 200/202 con el sobre del proxy\", function () {","    pm.expect([200, 202]).to.include(pm.response.code);","    var b = pm.response.json();","    pm.expect(b.success, \"success:false con status 2xx no debería pasar\").to.be.true;","    pm.expect(b).to.have.property(\"data\");","    var tarea = b.data && b.data.task_id;","    pm.expect(tarea, \"sin data.task_id no hay qué sondear\").to.be.a(\"string\");","    // Para `3 · Tareas → Estado y resultado de UNA tarea`.","    pm.collectionVariables.set(\"task_id\", tarea);","});"]}}]},{"name":"Policía - Antecedentes","request":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"X-Data-Authorization","value":"true","type":"text","description":"Ley 1581: declarás que contás con la autorización del titular para consultar sus datos. Es una declaración TUYA y queda registrada como evidencia. Sin este header la consulta se rechaza con 400 y no se cobra."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/services/verifycol/policia-antecedentes","host":["{{base_url}}"],"path":["api","v1","gateway","services","verifycol","policia-antecedentes"]},"description":"Policía — antecedentes judiciales (Policía Nacional). Certificado de antecedentes judiciales. Puede dar hallazgo.\n\nCosto: 1 crédito(s).\n\nTipos de documento aceptados: CC, CE, PA. Cualquier otro se rechaza con 422 y NO cobra créditos.\n\nASÍNCRONO: responde 202 con `task_id` y `status: \"QUEUED\"` (en MAYÚSCULAS). El resultado se recoge sondeando `/api/v1/gateway/services/verifycol/tasks/{task_id}` cada 2-5 s hasta `COMPLETED` o `FAILED`.\n\nRequiere el header `X-Data-Authorization: true` — Ley 1581. Es una declaración TUYA de que contás con la autorización del titular, y queda registrada como evidencia. Sin ella: 400, y no se cobra.\n\nEN EL SANDBOX (key `vf_test_`): el documento del ejemplo (900000003) es un sujeto del banco y responde su escenario, gratis. Con una key live va a la fuente real y se cobra: reemplazalo por el de un titular que te autorizó.","body":{"mode":"raw","raw":"{\n  \"documents\": [\n    {\n      \"tipo_documento\": \"CC\",\n      \"numero_documento\": \"900000003\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Policía - Antecedentes — ejemplo","originalRequest":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"X-Data-Authorization","value":"true","type":"text","description":"Ley 1581: declarás que contás con la autorización del titular para consultar sus datos. Es una declaración TUYA y queda registrada como evidencia. Sin este header la consulta se rechaza con 400 y no se cobra."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/services/verifycol/policia-antecedentes","host":["{{base_url}}"],"path":["api","v1","gateway","services","verifycol","policia-antecedentes"]},"description":"Policía — antecedentes judiciales (Policía Nacional). Certificado de antecedentes judiciales. Puede dar hallazgo.\n\nCosto: 1 crédito(s).\n\nTipos de documento aceptados: CC, CE, PA. Cualquier otro se rechaza con 422 y NO cobra créditos.\n\nASÍNCRONO: responde 202 con `task_id` y `status: \"QUEUED\"` (en MAYÚSCULAS). El resultado se recoge sondeando `/api/v1/gateway/services/verifycol/tasks/{task_id}` cada 2-5 s hasta `COMPLETED` o `FAILED`.\n\nRequiere el header `X-Data-Authorization: true` — Ley 1581. Es una declaración TUYA de que contás con la autorización del titular, y queda registrada como evidencia. Sin ella: 400, y no se cobra.\n\nEN EL SANDBOX (key `vf_test_`): el documento del ejemplo (900000003) es un sujeto del banco y responde su escenario, gratis. Con una key live va a la fuente real y se cobra: reemplazalo por el de un titular que te autorizó.","body":{"mode":"raw","raw":"{\n  \"documents\": [\n    {\n      \"tipo_documento\": \"CC\",\n      \"numero_documento\": \"900000003\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"status":"Accepted","code":202,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"task_id\": \"abc-127\",\n  \"status\": \"QUEUED\",\n  \"total\": 1,\n  \"type\": \"policia\",\n  \"message\": \"Tarea creada exitosamente\"\n}"}],"event":[{"listen":"test","script":{"type":"text/javascript","exec":["var sinCaso = pm.response.code === 400 &&","    pm.response.text().indexOf(\"sandbox_sin_caso\") >= 0;","if (sinCaso) {","    console.log(\"El sandbox no tiene escenario para esta fuente con este documento (sandbox_sin_caso): no se evaluó.\");","}","var t = sinCaso ? pm.test.skip : pm.test;","","t(\"La consulta responde 200/202 con el sobre del proxy\", function () {","    pm.expect([200, 202]).to.include(pm.response.code);","    var b = pm.response.json();","    pm.expect(b.success, \"success:false con status 2xx no debería pasar\").to.be.true;","    pm.expect(b).to.have.property(\"data\");","    var tarea = b.data && b.data.task_id;","    pm.expect(tarea, \"sin data.task_id no hay qué sondear\").to.be.a(\"string\");","    // Para `3 · Tareas → Estado y resultado de UNA tarea`.","    pm.collectionVariables.set(\"task_id\", tarea);","});"]}}]},{"name":"Policía - Medidas Correctivas","request":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"X-Data-Authorization","value":"true","type":"text","description":"Ley 1581: declarás que contás con la autorización del titular para consultar sus datos. Es una declaración TUYA y queda registrada como evidencia. Sin este header la consulta se rechaza con 400 y no se cobra."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/services/verifycol/policia-medidas-correctivas","host":["{{base_url}}"],"path":["api","v1","gateway","services","verifycol","policia-medidas-correctivas"]},"description":"Policía — medidas correctivas (Policía Nacional). Registro Nacional de Medidas Correctivas (Código de Policía). Puede dar hallazgo.\n\nCosto: 1 crédito(s).\n\nTipos de documento aceptados: CC, CE, TI, PA, NIT. Cualquier otro se rechaza con 422 y NO cobra créditos.\n\nASÍNCRONO: responde 202 con `task_id` y `status: \"QUEUED\"` (en MAYÚSCULAS). El resultado se recoge sondeando `/api/v1/gateway/services/verifycol/tasks/{task_id}` cada 2-5 s hasta `COMPLETED` o `FAILED`.\n\nRequiere el header `X-Data-Authorization: true` — Ley 1581. Es una declaración TUYA de que contás con la autorización del titular, y queda registrada como evidencia. Sin ella: 400, y no se cobra.\n\nEN EL SANDBOX (key `vf_test_`): el documento del ejemplo (900000003) es un sujeto del banco y responde su escenario, gratis. Con una key live va a la fuente real y se cobra: reemplazalo por el de un titular que te autorizó.","body":{"mode":"raw","raw":"{\n  \"documents\": [\n    {\n      \"tipo_documento\": \"CC\",\n      \"numero_documento\": \"900000003\",\n      \"fecha_expedicion\": \"01/01/2000\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Policía - Medidas Correctivas — ejemplo","originalRequest":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"X-Data-Authorization","value":"true","type":"text","description":"Ley 1581: declarás que contás con la autorización del titular para consultar sus datos. Es una declaración TUYA y queda registrada como evidencia. Sin este header la consulta se rechaza con 400 y no se cobra."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/services/verifycol/policia-medidas-correctivas","host":["{{base_url}}"],"path":["api","v1","gateway","services","verifycol","policia-medidas-correctivas"]},"description":"Policía — medidas correctivas (Policía Nacional). Registro Nacional de Medidas Correctivas (Código de Policía). Puede dar hallazgo.\n\nCosto: 1 crédito(s).\n\nTipos de documento aceptados: CC, CE, TI, PA, NIT. Cualquier otro se rechaza con 422 y NO cobra créditos.\n\nASÍNCRONO: responde 202 con `task_id` y `status: \"QUEUED\"` (en MAYÚSCULAS). El resultado se recoge sondeando `/api/v1/gateway/services/verifycol/tasks/{task_id}` cada 2-5 s hasta `COMPLETED` o `FAILED`.\n\nRequiere el header `X-Data-Authorization: true` — Ley 1581. Es una declaración TUYA de que contás con la autorización del titular, y queda registrada como evidencia. Sin ella: 400, y no se cobra.\n\nEN EL SANDBOX (key `vf_test_`): el documento del ejemplo (900000003) es un sujeto del banco y responde su escenario, gratis. Con una key live va a la fuente real y se cobra: reemplazalo por el de un titular que te autorizó.","body":{"mode":"raw","raw":"{\n  \"documents\": [\n    {\n      \"tipo_documento\": \"CC\",\n      \"numero_documento\": \"900000003\",\n      \"fecha_expedicion\": \"01/01/2000\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"status":"Accepted","code":202,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"task_id\": \"abc-128\",\n  \"status\": \"QUEUED\",\n  \"total\": 1,\n  \"type\": \"medidas_correctivas\",\n  \"message\": \"Tarea creada exitosamente\"\n}"}],"event":[{"listen":"test","script":{"type":"text/javascript","exec":["var sinCaso = pm.response.code === 400 &&","    pm.response.text().indexOf(\"sandbox_sin_caso\") >= 0;","if (sinCaso) {","    console.log(\"El sandbox no tiene escenario para esta fuente con este documento (sandbox_sin_caso): no se evaluó.\");","}","var t = sinCaso ? pm.test.skip : pm.test;","","t(\"La consulta responde 200/202 con el sobre del proxy\", function () {","    pm.expect([200, 202]).to.include(pm.response.code);","    var b = pm.response.json();","    pm.expect(b.success, \"success:false con status 2xx no debería pasar\").to.be.true;","    pm.expect(b).to.have.property(\"data\");","    var tarea = b.data && b.data.task_id;","    pm.expect(tarea, \"sin data.task_id no hay qué sondear\").to.be.a(\"string\");","    // Para `3 · Tareas → Estado y resultado de UNA tarea`.","    pm.collectionVariables.set(\"task_id\", tarea);","});"]}}]},{"name":"Procuraduría - Certificado Especial","request":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"X-Data-Authorization","value":"true","type":"text","description":"Ley 1581: declarás que contás con la autorización del titular para consultar sus datos. Es una declaración TUYA y queda registrada como evidencia. Sin este header la consulta se rechaza con 400 y no se cobra."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/services/verifycol/procuraduria-especial","host":["{{base_url}}"],"path":["api","v1","gateway","services","verifycol","procuraduria-especial"]},"description":"Procuraduría — certificado especial (Procuraduría General de la Nación). Antecedentes disciplinarios para el cargo que se indique. Puede dar hallazgo.\n\nCosto: 2 crédito(s).\n\nTipos de documento aceptados: CC, CE, PPT, NIT. Cualquier otro se rechaza con 422 y NO cobra créditos.\n\nASÍNCRONO: responde 202 con `task_id` y `status: \"QUEUED\"` (en MAYÚSCULAS). El resultado se recoge sondeando `/api/v1/gateway/services/verifycol/tasks/{task_id}` cada 2-5 s hasta `COMPLETED` o `FAILED`.\n\nRequiere el header `X-Data-Authorization: true` — Ley 1581. Es una declaración TUYA de que contás con la autorización del titular, y queda registrada como evidencia. Sin ella: 400, y no se cobra.\n\n⚠ SÓLO CON KEY LIVE. Esta fuente no tiene escenario en el sandbox: con una key de prueba (`vf_test_`) responde 400 `sandbox_sin_caso`, y en un reporte de prueba se omite con `reason: \"not_in_sandbox\"`. Con una key live la consulta va a la fuente real y se cobra: el documento del ejemplo es sintético en el sandbox: no lo uses con una key live; reemplazalo por el de un titular que te autorizó.","body":{"mode":"raw","raw":"{\n  \"documents\": [\n    {\n      \"tipo_documento\": \"CC\",\n      \"numero_documento\": \"900000003\",\n      \"cargo\": \"97\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Procuraduría - Certificado Especial — ejemplo","originalRequest":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"X-Data-Authorization","value":"true","type":"text","description":"Ley 1581: declarás que contás con la autorización del titular para consultar sus datos. Es una declaración TUYA y queda registrada como evidencia. Sin este header la consulta se rechaza con 400 y no se cobra."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/services/verifycol/procuraduria-especial","host":["{{base_url}}"],"path":["api","v1","gateway","services","verifycol","procuraduria-especial"]},"description":"Procuraduría — certificado especial (Procuraduría General de la Nación). Antecedentes disciplinarios para el cargo que se indique. Puede dar hallazgo.\n\nCosto: 2 crédito(s).\n\nTipos de documento aceptados: CC, CE, PPT, NIT. Cualquier otro se rechaza con 422 y NO cobra créditos.\n\nASÍNCRONO: responde 202 con `task_id` y `status: \"QUEUED\"` (en MAYÚSCULAS). El resultado se recoge sondeando `/api/v1/gateway/services/verifycol/tasks/{task_id}` cada 2-5 s hasta `COMPLETED` o `FAILED`.\n\nRequiere el header `X-Data-Authorization: true` — Ley 1581. Es una declaración TUYA de que contás con la autorización del titular, y queda registrada como evidencia. Sin ella: 400, y no se cobra.\n\n⚠ SÓLO CON KEY LIVE. Esta fuente no tiene escenario en el sandbox: con una key de prueba (`vf_test_`) responde 400 `sandbox_sin_caso`, y en un reporte de prueba se omite con `reason: \"not_in_sandbox\"`. Con una key live la consulta va a la fuente real y se cobra: el documento del ejemplo es sintético en el sandbox: no lo uses con una key live; reemplazalo por el de un titular que te autorizó.","body":{"mode":"raw","raw":"{\n  \"documents\": [\n    {\n      \"tipo_documento\": \"CC\",\n      \"numero_documento\": \"900000003\",\n      \"cargo\": \"97\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"status":"Accepted","code":202,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"task_id\": \"abc-126\",\n  \"status\": \"QUEUED\",\n  \"total\": 1,\n  \"type\": \"procuraduria_especial\",\n  \"message\": \"Tarea creada exitosamente\"\n}"}],"event":[{"listen":"test","script":{"type":"text/javascript","exec":["var sinCaso = pm.response.code === 400 &&","    pm.response.text().indexOf(\"sandbox_sin_caso\") >= 0;","if (sinCaso) {","    console.log(\"El sandbox no tiene escenario para esta fuente con este documento (sandbox_sin_caso): no se evaluó.\");","}","var t = sinCaso ? pm.test.skip : pm.test;","","t(\"La consulta responde 200/202 con el sobre del proxy\", function () {","    pm.expect([200, 202]).to.include(pm.response.code);","    var b = pm.response.json();","    pm.expect(b.success, \"success:false con status 2xx no debería pasar\").to.be.true;","    pm.expect(b).to.have.property(\"data\");","    var tarea = b.data && b.data.task_id;","    pm.expect(tarea, \"sin data.task_id no hay qué sondear\").to.be.a(\"string\");","    // Para `3 · Tareas → Estado y resultado de UNA tarea`.","    pm.collectionVariables.set(\"task_id\", tarea);","});"]}}]},{"name":"Procuraduría - Certificado Ordinario","request":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"X-Data-Authorization","value":"true","type":"text","description":"Ley 1581: declarás que contás con la autorización del titular para consultar sus datos. Es una declaración TUYA y queda registrada como evidencia. Sin este header la consulta se rechaza con 400 y no se cobra."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/services/verifycol/procuraduria-ordinario","host":["{{base_url}}"],"path":["api","v1","gateway","services","verifycol","procuraduria-ordinario"]},"description":"Procuraduría — certificado ordinario (Procuraduría General de la Nación). Antecedentes disciplinarios e inhabilidades registradas (SIRI). Puede dar hallazgo.\n\nCosto: 1 crédito(s).\n\nTipos de documento aceptados: CC, CE, PPT, NIT. Cualquier otro se rechaza con 422 y NO cobra créditos.\n\nASÍNCRONO: responde 202 con `task_id` y `status: \"QUEUED\"` (en MAYÚSCULAS). El resultado se recoge sondeando `/api/v1/gateway/services/verifycol/tasks/{task_id}` cada 2-5 s hasta `COMPLETED` o `FAILED`.\n\nRequiere el header `X-Data-Authorization: true` — Ley 1581. Es una declaración TUYA de que contás con la autorización del titular, y queda registrada como evidencia. Sin ella: 400, y no se cobra.\n\nEN EL SANDBOX (key `vf_test_`): el documento del ejemplo (900000008) es un sujeto del banco y responde su escenario, gratis. Con una key live va a la fuente real y se cobra: reemplazalo por el de un titular que te autorizó.","body":{"mode":"raw","raw":"{\n  \"documents\": [\n    {\n      \"tipo_documento\": \"NIT\",\n      \"numero_documento\": \"900000008\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Procuraduría - Certificado Ordinario — ejemplo","originalRequest":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"X-Data-Authorization","value":"true","type":"text","description":"Ley 1581: declarás que contás con la autorización del titular para consultar sus datos. Es una declaración TUYA y queda registrada como evidencia. Sin este header la consulta se rechaza con 400 y no se cobra."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/services/verifycol/procuraduria-ordinario","host":["{{base_url}}"],"path":["api","v1","gateway","services","verifycol","procuraduria-ordinario"]},"description":"Procuraduría — certificado ordinario (Procuraduría General de la Nación). Antecedentes disciplinarios e inhabilidades registradas (SIRI). Puede dar hallazgo.\n\nCosto: 1 crédito(s).\n\nTipos de documento aceptados: CC, CE, PPT, NIT. Cualquier otro se rechaza con 422 y NO cobra créditos.\n\nASÍNCRONO: responde 202 con `task_id` y `status: \"QUEUED\"` (en MAYÚSCULAS). El resultado se recoge sondeando `/api/v1/gateway/services/verifycol/tasks/{task_id}` cada 2-5 s hasta `COMPLETED` o `FAILED`.\n\nRequiere el header `X-Data-Authorization: true` — Ley 1581. Es una declaración TUYA de que contás con la autorización del titular, y queda registrada como evidencia. Sin ella: 400, y no se cobra.\n\nEN EL SANDBOX (key `vf_test_`): el documento del ejemplo (900000008) es un sujeto del banco y responde su escenario, gratis. Con una key live va a la fuente real y se cobra: reemplazalo por el de un titular que te autorizó.","body":{"mode":"raw","raw":"{\n  \"documents\": [\n    {\n      \"tipo_documento\": \"NIT\",\n      \"numero_documento\": \"900000008\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"status":"Accepted","code":202,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"task_id\": \"abc-125\",\n  \"status\": \"QUEUED\",\n  \"total\": 1,\n  \"type\": \"procuraduria_ordinario\",\n  \"message\": \"Tarea creada exitosamente\"\n}"}],"event":[{"listen":"test","script":{"type":"text/javascript","exec":["var sinCaso = pm.response.code === 400 &&","    pm.response.text().indexOf(\"sandbox_sin_caso\") >= 0;","if (sinCaso) {","    console.log(\"El sandbox no tiene escenario para esta fuente con este documento (sandbox_sin_caso): no se evaluó.\");","}","var t = sinCaso ? pm.test.skip : pm.test;","","t(\"La consulta responde 200/202 con el sobre del proxy\", function () {","    pm.expect([200, 202]).to.include(pm.response.code);","    var b = pm.response.json();","    pm.expect(b.success, \"success:false con status 2xx no debería pasar\").to.be.true;","    pm.expect(b).to.have.property(\"data\");","    var tarea = b.data && b.data.task_id;","    pm.expect(tarea, \"sin data.task_id no hay qué sondear\").to.be.a(\"string\");","    // Para `3 · Tareas → Estado y resultado de UNA tarea`.","    pm.collectionVariables.set(\"task_id\", tarea);","});"]}}]},{"name":"Rama Judicial — Procesos (CPNU)","request":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"X-Data-Authorization","value":"true","type":"text","description":"Ley 1581: declarás que contás con la autorización del titular para consultar sus datos. Es una declaración TUYA y queda registrada como evidencia. Sin este header la consulta se rechaza con 400 y no se cobra."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/services/verifycol/rama-judicial-procesos","host":["{{base_url}}"],"path":["api","v1","gateway","services","verifycol","rama-judicial-procesos"]},"description":"Rama Judicial — procesos (Rama Judicial). Procesos judiciales donde figura como parte (demandante o demandado). Puede dar hallazgo.\n\nCosto: 1 crédito(s).\n\nASÍNCRONO: responde 202 con `task_id` y `status: \"QUEUED\"` (en MAYÚSCULAS). El resultado se recoge sondeando `/api/v1/gateway/services/verifycol/tasks/{task_id}` cada 2-5 s hasta `COMPLETED` o `FAILED`.\n\nRequiere el header `X-Data-Authorization: true` — Ley 1581. Es una declaración TUYA de que contás con la autorización del titular, y queda registrada como evidencia. Sin ella: 400, y no se cobra.\n\n⚠ SÓLO CON KEY LIVE. Esta fuente no tiene escenario en el sandbox: con una key de prueba (`vf_test_`) responde 400 `sandbox_sin_caso`, y en un reporte de prueba se omite con `reason: \"not_in_sandbox\"`. Con una key live la consulta va a la fuente real y se cobra: el documento del ejemplo es sintético en el sandbox: no lo uses con una key live; reemplazalo por el de un titular que te autorizó.","body":{"mode":"raw","raw":"{\n  \"documents\": [\n    {\n      \"nombre\": \"SUJETO DE PRUEBA VERIFYCOL\",\n      \"tipo_persona\": \"nat\",\n      \"incluir_detalle\": true\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Rama Judicial — Procesos (CPNU) — ejemplo","originalRequest":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"X-Data-Authorization","value":"true","type":"text","description":"Ley 1581: declarás que contás con la autorización del titular para consultar sus datos. Es una declaración TUYA y queda registrada como evidencia. Sin este header la consulta se rechaza con 400 y no se cobra."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/services/verifycol/rama-judicial-procesos","host":["{{base_url}}"],"path":["api","v1","gateway","services","verifycol","rama-judicial-procesos"]},"description":"Rama Judicial — procesos (Rama Judicial). Procesos judiciales donde figura como parte (demandante o demandado). Puede dar hallazgo.\n\nCosto: 1 crédito(s).\n\nASÍNCRONO: responde 202 con `task_id` y `status: \"QUEUED\"` (en MAYÚSCULAS). El resultado se recoge sondeando `/api/v1/gateway/services/verifycol/tasks/{task_id}` cada 2-5 s hasta `COMPLETED` o `FAILED`.\n\nRequiere el header `X-Data-Authorization: true` — Ley 1581. Es una declaración TUYA de que contás con la autorización del titular, y queda registrada como evidencia. Sin ella: 400, y no se cobra.\n\n⚠ SÓLO CON KEY LIVE. Esta fuente no tiene escenario en el sandbox: con una key de prueba (`vf_test_`) responde 400 `sandbox_sin_caso`, y en un reporte de prueba se omite con `reason: \"not_in_sandbox\"`. Con una key live la consulta va a la fuente real y se cobra: el documento del ejemplo es sintético en el sandbox: no lo uses con una key live; reemplazalo por el de un titular que te autorizó.","body":{"mode":"raw","raw":"{\n  \"documents\": [\n    {\n      \"nombre\": \"SUJETO DE PRUEBA VERIFYCOL\",\n      \"tipo_persona\": \"nat\",\n      \"incluir_detalle\": true\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"status":"Accepted","code":202,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"task_id\": \"abc-123-def\",\n  \"status\": \"QUEUED\",\n  \"total\": 1,\n  \"type\": \"rama_judicial\",\n  \"message\": \"1 consulta(s) encolada(s) para verificación en Rama Judicial\"\n}"}],"event":[{"listen":"test","script":{"type":"text/javascript","exec":["var sinCaso = pm.response.code === 400 &&","    pm.response.text().indexOf(\"sandbox_sin_caso\") >= 0;","if (sinCaso) {","    console.log(\"El sandbox no tiene escenario para esta fuente con este documento (sandbox_sin_caso): no se evaluó.\");","}","var t = sinCaso ? pm.test.skip : pm.test;","","t(\"La consulta responde 200/202 con el sobre del proxy\", function () {","    pm.expect([200, 202]).to.include(pm.response.code);","    var b = pm.response.json();","    pm.expect(b.success, \"success:false con status 2xx no debería pasar\").to.be.true;","    pm.expect(b).to.have.property(\"data\");","    var tarea = b.data && b.data.task_id;","    pm.expect(tarea, \"sin data.task_id no hay qué sondear\").to.be.a(\"string\");","    // Para `3 · Tareas → Estado y resultado de UNA tarea`.","    pm.collectionVariables.set(\"task_id\", tarea);","});"]}}]}]},{"name":"Identidad y migración","item":[{"name":"Migración Colombia — Cédula de Extranjería","request":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"X-Data-Authorization","value":"true","type":"text","description":"Ley 1581: declarás que contás con la autorización del titular para consultar sus datos. Es una declaración TUYA y queda registrada como evidencia. Sin este header la consulta se rechaza con 400 y no se cobra."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/services/verifycol/migracion-cedula-extranjeria","host":["{{base_url}}"],"path":["api","v1","gateway","services","verifycol","migracion-cedula-extranjeria"]},"description":"Migración Colombia — cédula de extranjería (Migración Colombia). Estado de la cédula de extranjería. Informativa.\n\nCosto: 1 crédito(s).\n\nASÍNCRONO: responde 202 con `task_id` y `status: \"QUEUED\"` (en MAYÚSCULAS). El resultado se recoge sondeando `/api/v1/gateway/services/verifycol/tasks/{task_id}` cada 2-5 s hasta `COMPLETED` o `FAILED`.\n\nRequiere el header `X-Data-Authorization: true` — Ley 1581. Es una declaración TUYA de que contás con la autorización del titular, y queda registrada como evidencia. Sin ella: 400, y no se cobra.\n\n⚠ SÓLO CON KEY LIVE. Esta fuente no tiene escenario en el sandbox: con una key de prueba (`vf_test_`) responde 400 `sandbox_sin_caso`, y en un reporte de prueba se omite con `reason: \"not_in_sandbox\"`. Con una key live la consulta va a la fuente real y se cobra: el documento del ejemplo es sintético en el sandbox: no lo uses con una key live; reemplazalo por el de un titular que te autorizó.","body":{"mode":"raw","raw":"{\n  \"documents\": [\n    {\n      \"numero_documento\": \"900000003\",\n      \"fecha_expedicion\": \"2022-01-15\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Migración Colombia — Cédula de Extranjería — ejemplo","originalRequest":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"X-Data-Authorization","value":"true","type":"text","description":"Ley 1581: declarás que contás con la autorización del titular para consultar sus datos. Es una declaración TUYA y queda registrada como evidencia. Sin este header la consulta se rechaza con 400 y no se cobra."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/services/verifycol/migracion-cedula-extranjeria","host":["{{base_url}}"],"path":["api","v1","gateway","services","verifycol","migracion-cedula-extranjeria"]},"description":"Migración Colombia — cédula de extranjería (Migración Colombia). Estado de la cédula de extranjería. Informativa.\n\nCosto: 1 crédito(s).\n\nASÍNCRONO: responde 202 con `task_id` y `status: \"QUEUED\"` (en MAYÚSCULAS). El resultado se recoge sondeando `/api/v1/gateway/services/verifycol/tasks/{task_id}` cada 2-5 s hasta `COMPLETED` o `FAILED`.\n\nRequiere el header `X-Data-Authorization: true` — Ley 1581. Es una declaración TUYA de que contás con la autorización del titular, y queda registrada como evidencia. Sin ella: 400, y no se cobra.\n\n⚠ SÓLO CON KEY LIVE. Esta fuente no tiene escenario en el sandbox: con una key de prueba (`vf_test_`) responde 400 `sandbox_sin_caso`, y en un reporte de prueba se omite con `reason: \"not_in_sandbox\"`. Con una key live la consulta va a la fuente real y se cobra: el documento del ejemplo es sintético en el sandbox: no lo uses con una key live; reemplazalo por el de un titular que te autorizó.","body":{"mode":"raw","raw":"{\n  \"documents\": [\n    {\n      \"numero_documento\": \"900000003\",\n      \"fecha_expedicion\": \"2022-01-15\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"status":"Accepted","code":202,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"task_id\": \"abc-143\",\n  \"status\": \"QUEUED\",\n  \"total\": 1,\n  \"type\": \"migracion_ce\",\n  \"message\": \"1 Cédula(s) de Extranjería encolada(s) para consulta en Migración Colombia\"\n}"}],"event":[{"listen":"test","script":{"type":"text/javascript","exec":["var sinCaso = pm.response.code === 400 &&","    pm.response.text().indexOf(\"sandbox_sin_caso\") >= 0;","if (sinCaso) {","    console.log(\"El sandbox no tiene escenario para esta fuente con este documento (sandbox_sin_caso): no se evaluó.\");","}","var t = sinCaso ? pm.test.skip : pm.test;","","t(\"La consulta responde 200/202 con el sobre del proxy\", function () {","    pm.expect([200, 202]).to.include(pm.response.code);","    var b = pm.response.json();","    pm.expect(b.success, \"success:false con status 2xx no debería pasar\").to.be.true;","    pm.expect(b).to.have.property(\"data\");","    var tarea = b.data && b.data.task_id;","    pm.expect(tarea, \"sin data.task_id no hay qué sondear\").to.be.a(\"string\");","    // Para `3 · Tareas → Estado y resultado de UNA tarea`.","    pm.collectionVariables.set(\"task_id\", tarea);","});"]}}]},{"name":"Migración Colombia — Permiso por Protección Temporal (PPT)","request":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"X-Data-Authorization","value":"true","type":"text","description":"Ley 1581: declarás que contás con la autorización del titular para consultar sus datos. Es una declaración TUYA y queda registrada como evidencia. Sin este header la consulta se rechaza con 400 y no se cobra."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/services/verifycol/migracion-ppt","host":["{{base_url}}"],"path":["api","v1","gateway","services","verifycol","migracion-ppt"]},"description":"Migración Colombia — PPT (Migración Colombia). Estado del Permiso por Protección Temporal. Informativa.\n\nCosto: 1 crédito(s).\n\nASÍNCRONO: responde 202 con `task_id` y `status: \"QUEUED\"` (en MAYÚSCULAS). El resultado se recoge sondeando `/api/v1/gateway/services/verifycol/tasks/{task_id}` cada 2-5 s hasta `COMPLETED` o `FAILED`.\n\nRequiere el header `X-Data-Authorization: true` — Ley 1581. Es una declaración TUYA de que contás con la autorización del titular, y queda registrada como evidencia. Sin ella: 400, y no se cobra.\n\n⚠ SÓLO CON KEY LIVE. Esta fuente no tiene escenario en el sandbox: con una key de prueba (`vf_test_`) responde 400 `sandbox_sin_caso`, y en un reporte de prueba se omite con `reason: \"not_in_sandbox\"`. Con una key live la consulta va a la fuente real y se cobra: el documento del ejemplo es sintético en el sandbox: no lo uses con una key live; reemplazalo por el de un titular que te autorizó.","body":{"mode":"raw","raw":"{\n  \"documents\": [\n    {\n      \"numero_documento\": \"900000003\",\n      \"fecha_expedicion\": \"2022-01-15\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Migración Colombia — Permiso por Protección Temporal (PPT) — ejemplo","originalRequest":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"X-Data-Authorization","value":"true","type":"text","description":"Ley 1581: declarás que contás con la autorización del titular para consultar sus datos. Es una declaración TUYA y queda registrada como evidencia. Sin este header la consulta se rechaza con 400 y no se cobra."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/services/verifycol/migracion-ppt","host":["{{base_url}}"],"path":["api","v1","gateway","services","verifycol","migracion-ppt"]},"description":"Migración Colombia — PPT (Migración Colombia). Estado del Permiso por Protección Temporal. Informativa.\n\nCosto: 1 crédito(s).\n\nASÍNCRONO: responde 202 con `task_id` y `status: \"QUEUED\"` (en MAYÚSCULAS). El resultado se recoge sondeando `/api/v1/gateway/services/verifycol/tasks/{task_id}` cada 2-5 s hasta `COMPLETED` o `FAILED`.\n\nRequiere el header `X-Data-Authorization: true` — Ley 1581. Es una declaración TUYA de que contás con la autorización del titular, y queda registrada como evidencia. Sin ella: 400, y no se cobra.\n\n⚠ SÓLO CON KEY LIVE. Esta fuente no tiene escenario en el sandbox: con una key de prueba (`vf_test_`) responde 400 `sandbox_sin_caso`, y en un reporte de prueba se omite con `reason: \"not_in_sandbox\"`. Con una key live la consulta va a la fuente real y se cobra: el documento del ejemplo es sintético en el sandbox: no lo uses con una key live; reemplazalo por el de un titular que te autorizó.","body":{"mode":"raw","raw":"{\n  \"documents\": [\n    {\n      \"numero_documento\": \"900000003\",\n      \"fecha_expedicion\": \"2022-01-15\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"status":"Accepted","code":202,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"task_id\": \"abc-143\",\n  \"status\": \"QUEUED\",\n  \"total\": 1,\n  \"type\": \"migracion_ppt\",\n  \"message\": \"1 PPT encolado(s) para consulta en Migración Colombia\"\n}"}],"event":[{"listen":"test","script":{"type":"text/javascript","exec":["var sinCaso = pm.response.code === 400 &&","    pm.response.text().indexOf(\"sandbox_sin_caso\") >= 0;","if (sinCaso) {","    console.log(\"El sandbox no tiene escenario para esta fuente con este documento (sandbox_sin_caso): no se evaluó.\");","}","var t = sinCaso ? pm.test.skip : pm.test;","","t(\"La consulta responde 200/202 con el sobre del proxy\", function () {","    pm.expect([200, 202]).to.include(pm.response.code);","    var b = pm.response.json();","    pm.expect(b.success, \"success:false con status 2xx no debería pasar\").to.be.true;","    pm.expect(b).to.have.property(\"data\");","    var tarea = b.data && b.data.task_id;","    pm.expect(tarea, \"sin data.task_id no hay qué sondear\").to.be.a(\"string\");","    // Para `3 · Tareas → Estado y resultado de UNA tarea`.","    pm.collectionVariables.set(\"task_id\", tarea);","});"]}}]},{"name":"Registraduría — Vigencia de la cédula","request":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"X-Data-Authorization","value":"true","type":"text","description":"Ley 1581: declarás que contás con la autorización del titular para consultar sus datos. Es una declaración TUYA y queda registrada como evidencia. Sin este header la consulta se rechaza con 400 y no se cobra."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/services/verifycol/registraduria-vigencia","host":["{{base_url}}"],"path":["api","v1","gateway","services","verifycol","registraduria-vigencia"]},"description":"Registraduría — vigencia de la cédula (Registraduría Nacional del Estado Civil). Estado de la cédula (vigente, cancelada por muerte…), nombre, fecha y lugar de expedición. Informativa.\n\nCosto: 1 crédito(s).\n\nASÍNCRONO: responde 202 con `task_id` y `status: \"QUEUED\"` (en MAYÚSCULAS). El resultado se recoge sondeando `/api/v1/gateway/services/verifycol/tasks/{task_id}` cada 2-5 s hasta `COMPLETED` o `FAILED`.\n\nRequiere el header `X-Data-Authorization: true` — Ley 1581. Es una declaración TUYA de que contás con la autorización del titular, y queda registrada como evidencia. Sin ella: 400, y no se cobra.\n\n⚠ SÓLO CON KEY LIVE. Esta fuente no tiene escenario en el sandbox: con una key de prueba (`vf_test_`) responde 400 `sandbox_sin_caso`, y en un reporte de prueba se omite con `reason: \"not_in_sandbox\"`. Con una key live la consulta va a la fuente real y se cobra: el documento del ejemplo es sintético en el sandbox: no lo uses con una key live; reemplazalo por el de un titular que te autorizó.","body":{"mode":"raw","raw":"{\n  \"documents\": [\n    {\n      \"numero_documento\": \"900000003\",\n      \"fecha_expedicion\": \"2001-03-15\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Registraduría — Vigencia de la cédula — ejemplo","originalRequest":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"X-Data-Authorization","value":"true","type":"text","description":"Ley 1581: declarás que contás con la autorización del titular para consultar sus datos. Es una declaración TUYA y queda registrada como evidencia. Sin este header la consulta se rechaza con 400 y no se cobra."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/services/verifycol/registraduria-vigencia","host":["{{base_url}}"],"path":["api","v1","gateway","services","verifycol","registraduria-vigencia"]},"description":"Registraduría — vigencia de la cédula (Registraduría Nacional del Estado Civil). Estado de la cédula (vigente, cancelada por muerte…), nombre, fecha y lugar de expedición. Informativa.\n\nCosto: 1 crédito(s).\n\nASÍNCRONO: responde 202 con `task_id` y `status: \"QUEUED\"` (en MAYÚSCULAS). El resultado se recoge sondeando `/api/v1/gateway/services/verifycol/tasks/{task_id}` cada 2-5 s hasta `COMPLETED` o `FAILED`.\n\nRequiere el header `X-Data-Authorization: true` — Ley 1581. Es una declaración TUYA de que contás con la autorización del titular, y queda registrada como evidencia. Sin ella: 400, y no se cobra.\n\n⚠ SÓLO CON KEY LIVE. Esta fuente no tiene escenario en el sandbox: con una key de prueba (`vf_test_`) responde 400 `sandbox_sin_caso`, y en un reporte de prueba se omite con `reason: \"not_in_sandbox\"`. Con una key live la consulta va a la fuente real y se cobra: el documento del ejemplo es sintético en el sandbox: no lo uses con una key live; reemplazalo por el de un titular que te autorizó.","body":{"mode":"raw","raw":"{\n  \"documents\": [\n    {\n      \"numero_documento\": \"900000003\",\n      \"fecha_expedicion\": \"2001-03-15\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"status":"Accepted","code":202,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"task_id\": \"abc-143\",\n  \"status\": \"QUEUED\",\n  \"total\": 1,\n  \"type\": \"registraduria\",\n  \"message\": \"Consulta de vigencia de cédula encolada\"\n}"}],"event":[{"listen":"test","script":{"type":"text/javascript","exec":["var sinCaso = pm.response.code === 400 &&","    pm.response.text().indexOf(\"sandbox_sin_caso\") >= 0;","if (sinCaso) {","    console.log(\"El sandbox no tiene escenario para esta fuente con este documento (sandbox_sin_caso): no se evaluó.\");","}","var t = sinCaso ? pm.test.skip : pm.test;","","t(\"La consulta responde 200/202 con el sobre del proxy\", function () {","    pm.expect([200, 202]).to.include(pm.response.code);","    var b = pm.response.json();","    pm.expect(b.success, \"success:false con status 2xx no debería pasar\").to.be.true;","    pm.expect(b).to.have.property(\"data\");","    var tarea = b.data && b.data.task_id;","    pm.expect(tarea, \"sin data.task_id no hay qué sondear\").to.be.a(\"string\");","    // Para `3 · Tareas → Estado y resultado de UNA tarea`.","    pm.collectionVariables.set(\"task_id\", tarea);","});"]}}]}]},{"name":"Salud y afiliación","item":[{"name":"ADRES - Afiliados Compensados","request":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"X-Data-Authorization","value":"true","type":"text","description":"Ley 1581: declarás que contás con la autorización del titular para consultar sus datos. Es una declaración TUYA y queda registrada como evidencia. Sin este header la consulta se rechaza con 400 y no se cobra."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/services/verifycol/adres-afiliados-compensados","host":["{{base_url}}"],"path":["api","v1","gateway","services","verifycol","adres-afiliados-compensados"]},"description":"ADRES — afiliados compensados (ADRES). Periodos compensados: EPS o EOC, días y tipo de afiliado. Informativa.\n\nCosto: 1 crédito(s).\n\nTipos de documento aceptados: CC, CE, TI, PA, PPT, NIT. Cualquier otro se rechaza con 422 y NO cobra créditos.\n\nASÍNCRONO: responde 202 con `task_id` y `status: \"QUEUED\"` (en MAYÚSCULAS). El resultado se recoge sondeando `/api/v1/gateway/services/verifycol/tasks/{task_id}` cada 2-5 s hasta `COMPLETED` o `FAILED`.\n\nRequiere el header `X-Data-Authorization: true` — Ley 1581. Es una declaración TUYA de que contás con la autorización del titular, y queda registrada como evidencia. Sin ella: 400, y no se cobra.\n\nEN EL SANDBOX (key `vf_test_`): el documento del ejemplo (900000003) es un sujeto del banco y responde su escenario, gratis. Con una key live va a la fuente real y se cobra: reemplazalo por el de un titular que te autorizó.","body":{"mode":"raw","raw":"{\n  \"documents\": [\n    {\n      \"tipo_documento\": \"CC\",\n      \"numero_documento\": \"900000003\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"ADRES - Afiliados Compensados — ejemplo","originalRequest":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"X-Data-Authorization","value":"true","type":"text","description":"Ley 1581: declarás que contás con la autorización del titular para consultar sus datos. Es una declaración TUYA y queda registrada como evidencia. Sin este header la consulta se rechaza con 400 y no se cobra."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/services/verifycol/adres-afiliados-compensados","host":["{{base_url}}"],"path":["api","v1","gateway","services","verifycol","adres-afiliados-compensados"]},"description":"ADRES — afiliados compensados (ADRES). Periodos compensados: EPS o EOC, días y tipo de afiliado. Informativa.\n\nCosto: 1 crédito(s).\n\nTipos de documento aceptados: CC, CE, TI, PA, PPT, NIT. Cualquier otro se rechaza con 422 y NO cobra créditos.\n\nASÍNCRONO: responde 202 con `task_id` y `status: \"QUEUED\"` (en MAYÚSCULAS). El resultado se recoge sondeando `/api/v1/gateway/services/verifycol/tasks/{task_id}` cada 2-5 s hasta `COMPLETED` o `FAILED`.\n\nRequiere el header `X-Data-Authorization: true` — Ley 1581. Es una declaración TUYA de que contás con la autorización del titular, y queda registrada como evidencia. Sin ella: 400, y no se cobra.\n\nEN EL SANDBOX (key `vf_test_`): el documento del ejemplo (900000003) es un sujeto del banco y responde su escenario, gratis. Con una key live va a la fuente real y se cobra: reemplazalo por el de un titular que te autorizó.","body":{"mode":"raw","raw":"{\n  \"documents\": [\n    {\n      \"tipo_documento\": \"CC\",\n      \"numero_documento\": \"900000003\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"status":"Accepted","code":202,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"task_id\": \"abc-1\",\n  \"status\": \"QUEUED\",\n  \"total\": 1,\n  \"type\": \"adres_afiliados\",\n  \"message\": \"1 documento(s) encolado(s)...\"\n}"}],"event":[{"listen":"test","script":{"type":"text/javascript","exec":["var sinCaso = pm.response.code === 400 &&","    pm.response.text().indexOf(\"sandbox_sin_caso\") >= 0;","if (sinCaso) {","    console.log(\"El sandbox no tiene escenario para esta fuente con este documento (sandbox_sin_caso): no se evaluó.\");","}","var t = sinCaso ? pm.test.skip : pm.test;","","t(\"La consulta responde 200/202 con el sobre del proxy\", function () {","    pm.expect([200, 202]).to.include(pm.response.code);","    var b = pm.response.json();","    pm.expect(b.success, \"success:false con status 2xx no debería pasar\").to.be.true;","    pm.expect(b).to.have.property(\"data\");","    var tarea = b.data && b.data.task_id;","    pm.expect(tarea, \"sin data.task_id no hay qué sondear\").to.be.a(\"string\");","    // Para `3 · Tareas → Estado y resultado de UNA tarea`.","    pm.collectionVariables.set(\"task_id\", tarea);","});"]}}]},{"name":"ADRES BDUA - Afiliación en Salud","request":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"X-Data-Authorization","value":"true","type":"text","description":"Ley 1581: declarás que contás con la autorización del titular para consultar sus datos. Es una declaración TUYA y queda registrada como evidencia. Sin este header la consulta se rechaza con 400 y no se cobra."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/services/verifycol/adres-bdua","host":["{{base_url}}"],"path":["api","v1","gateway","services","verifycol","adres-bdua"]},"description":"ADRES — afiliación en salud (ADRES). Afiliación vigente en salud: EPS, régimen, estado y tipo de afiliado. Informativa.\n\nCosto: 1 crédito(s).\n\nTipos de documento aceptados: CC, CE, TI, PA, PPT. Cualquier otro se rechaza con 422 y NO cobra créditos.\n\nASÍNCRONO: responde 202 con `task_id` y `status: \"QUEUED\"` (en MAYÚSCULAS). El resultado se recoge sondeando `/api/v1/gateway/services/verifycol/tasks/{task_id}` cada 2-5 s hasta `COMPLETED` o `FAILED`.\n\nRequiere el header `X-Data-Authorization: true` — Ley 1581. Es una declaración TUYA de que contás con la autorización del titular, y queda registrada como evidencia. Sin ella: 400, y no se cobra.\n\n⚠ SÓLO CON KEY LIVE. Esta fuente no tiene escenario en el sandbox: con una key de prueba (`vf_test_`) responde 400 `sandbox_sin_caso`, y en un reporte de prueba se omite con `reason: \"not_in_sandbox\"`. Con una key live la consulta va a la fuente real y se cobra: el documento del ejemplo es sintético en el sandbox: no lo uses con una key live; reemplazalo por el de un titular que te autorizó.","body":{"mode":"raw","raw":"{\n  \"documents\": [\n    {\n      \"tipo_documento\": \"CC\",\n      \"numero_documento\": \"900000003\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"ADRES BDUA - Afiliación en Salud — ejemplo","originalRequest":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"X-Data-Authorization","value":"true","type":"text","description":"Ley 1581: declarás que contás con la autorización del titular para consultar sus datos. Es una declaración TUYA y queda registrada como evidencia. Sin este header la consulta se rechaza con 400 y no se cobra."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/services/verifycol/adres-bdua","host":["{{base_url}}"],"path":["api","v1","gateway","services","verifycol","adres-bdua"]},"description":"ADRES — afiliación en salud (ADRES). Afiliación vigente en salud: EPS, régimen, estado y tipo de afiliado. Informativa.\n\nCosto: 1 crédito(s).\n\nTipos de documento aceptados: CC, CE, TI, PA, PPT. Cualquier otro se rechaza con 422 y NO cobra créditos.\n\nASÍNCRONO: responde 202 con `task_id` y `status: \"QUEUED\"` (en MAYÚSCULAS). El resultado se recoge sondeando `/api/v1/gateway/services/verifycol/tasks/{task_id}` cada 2-5 s hasta `COMPLETED` o `FAILED`.\n\nRequiere el header `X-Data-Authorization: true` — Ley 1581. Es una declaración TUYA de que contás con la autorización del titular, y queda registrada como evidencia. Sin ella: 400, y no se cobra.\n\n⚠ SÓLO CON KEY LIVE. Esta fuente no tiene escenario en el sandbox: con una key de prueba (`vf_test_`) responde 400 `sandbox_sin_caso`, y en un reporte de prueba se omite con `reason: \"not_in_sandbox\"`. Con una key live la consulta va a la fuente real y se cobra: el documento del ejemplo es sintético en el sandbox: no lo uses con una key live; reemplazalo por el de un titular que te autorizó.","body":{"mode":"raw","raw":"{\n  \"documents\": [\n    {\n      \"tipo_documento\": \"CC\",\n      \"numero_documento\": \"900000003\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"status":"Accepted","code":202,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"task_id\": \"abc-1\",\n  \"status\": \"QUEUED\",\n  \"total\": 1,\n  \"type\": \"adres_bdua\",\n  \"message\": \"1 documento(s) encolado(s)...\"\n}"}],"event":[{"listen":"test","script":{"type":"text/javascript","exec":["var sinCaso = pm.response.code === 400 &&","    pm.response.text().indexOf(\"sandbox_sin_caso\") >= 0;","if (sinCaso) {","    console.log(\"El sandbox no tiene escenario para esta fuente con este documento (sandbox_sin_caso): no se evaluó.\");","}","var t = sinCaso ? pm.test.skip : pm.test;","","t(\"La consulta responde 200/202 con el sobre del proxy\", function () {","    pm.expect([200, 202]).to.include(pm.response.code);","    var b = pm.response.json();","    pm.expect(b.success, \"success:false con status 2xx no debería pasar\").to.be.true;","    pm.expect(b).to.have.property(\"data\");","    var tarea = b.data && b.data.task_id;","    pm.expect(tarea, \"sin data.task_id no hay qué sondear\").to.be.a(\"string\");","    // Para `3 · Tareas → Estado y resultado de UNA tarea`.","    pm.collectionVariables.set(\"task_id\", tarea);","});"]}}]}]},{"name":"Tránsito","item":[{"name":"RUNT - Consulta de vehículo","request":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"X-Data-Authorization","value":"true","type":"text","description":"Ley 1581: declarás que contás con la autorización del titular para consultar sus datos. Es una declaración TUYA y queda registrada como evidencia. Sin este header la consulta se rechaza con 400 y no se cobra."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/services/verifycol/runt-consultar","host":["{{base_url}}"],"path":["api","v1","gateway","services","verifycol","runt-consultar"]},"description":"RUNT — vehículo (RUNT). Ficha del vehículo, SOAT, revisión técnico-mecánica, prendas y limitaciones. Informativa.\n\nCosto: 1 crédito(s).\n\nTipos de documento aceptados: CC, CE, TI, PA, PPT, NIT. Cualquier otro se rechaza con 422 y NO cobra créditos.\n\nASÍNCRONO: responde 202 con `task_id` y `status: \"QUEUED\"` (en MAYÚSCULAS). El resultado se recoge sondeando `/api/v1/gateway/services/verifycol/tasks/{task_id}` cada 2-5 s hasta `COMPLETED` o `FAILED`.\n\nRequiere el header `X-Data-Authorization: true` — Ley 1581. Es una declaración TUYA de que contás con la autorización del titular, y queda registrada como evidencia. Sin ella: 400, y no se cobra.\n\n⚠ SÓLO CON KEY LIVE. Esta fuente no tiene escenario en el sandbox: con una key de prueba (`vf_test_`) responde 400 `sandbox_sin_caso`, y en un reporte de prueba se omite con `reason: \"not_in_sandbox\"`. Con una key live la consulta va a la fuente real y se cobra: el documento del ejemplo es sintético en el sandbox: no lo uses con una key live; reemplazalo por el de un titular que te autorizó.","body":{"mode":"raw","raw":"{\n  \"documents\": [\n    {\n      \"tipo_documento\": \"CC\",\n      \"numero_documento\": \"900000003\",\n      \"placa\": \"ABC123\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"RUNT - Consulta de vehículo — ejemplo","originalRequest":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"X-Data-Authorization","value":"true","type":"text","description":"Ley 1581: declarás que contás con la autorización del titular para consultar sus datos. Es una declaración TUYA y queda registrada como evidencia. Sin este header la consulta se rechaza con 400 y no se cobra."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/services/verifycol/runt-consultar","host":["{{base_url}}"],"path":["api","v1","gateway","services","verifycol","runt-consultar"]},"description":"RUNT — vehículo (RUNT). Ficha del vehículo, SOAT, revisión técnico-mecánica, prendas y limitaciones. Informativa.\n\nCosto: 1 crédito(s).\n\nTipos de documento aceptados: CC, CE, TI, PA, PPT, NIT. Cualquier otro se rechaza con 422 y NO cobra créditos.\n\nASÍNCRONO: responde 202 con `task_id` y `status: \"QUEUED\"` (en MAYÚSCULAS). El resultado se recoge sondeando `/api/v1/gateway/services/verifycol/tasks/{task_id}` cada 2-5 s hasta `COMPLETED` o `FAILED`.\n\nRequiere el header `X-Data-Authorization: true` — Ley 1581. Es una declaración TUYA de que contás con la autorización del titular, y queda registrada como evidencia. Sin ella: 400, y no se cobra.\n\n⚠ SÓLO CON KEY LIVE. Esta fuente no tiene escenario en el sandbox: con una key de prueba (`vf_test_`) responde 400 `sandbox_sin_caso`, y en un reporte de prueba se omite con `reason: \"not_in_sandbox\"`. Con una key live la consulta va a la fuente real y se cobra: el documento del ejemplo es sintético en el sandbox: no lo uses con una key live; reemplazalo por el de un titular que te autorizó.","body":{"mode":"raw","raw":"{\n  \"documents\": [\n    {\n      \"tipo_documento\": \"CC\",\n      \"numero_documento\": \"900000003\",\n      \"placa\": \"ABC123\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"status":"Accepted","code":202,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"task_id\": \"abc-140\",\n  \"status\": \"QUEUED\",\n  \"total\": 1,\n  \"type\": \"runt\",\n  \"message\": \"1 vehículo(s) encolado(s) para consulta en RUNT\"\n}"}],"event":[{"listen":"test","script":{"type":"text/javascript","exec":["var sinCaso = pm.response.code === 400 &&","    pm.response.text().indexOf(\"sandbox_sin_caso\") >= 0;","if (sinCaso) {","    console.log(\"El sandbox no tiene escenario para esta fuente con este documento (sandbox_sin_caso): no se evaluó.\");","}","var t = sinCaso ? pm.test.skip : pm.test;","","t(\"La consulta responde 200/202 con el sobre del proxy\", function () {","    pm.expect([200, 202]).to.include(pm.response.code);","    var b = pm.response.json();","    pm.expect(b.success, \"success:false con status 2xx no debería pasar\").to.be.true;","    pm.expect(b).to.have.property(\"data\");","    var tarea = b.data && b.data.task_id;","    pm.expect(tarea, \"sin data.task_id no hay qué sondear\").to.be.a(\"string\");","    // Para `3 · Tareas → Estado y resultado de UNA tarea`.","    pm.collectionVariables.set(\"task_id\", tarea);","});"]}}]},{"name":"RUNT Persona - Consulta ciudadano","request":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"X-Data-Authorization","value":"true","type":"text","description":"Ley 1581: declarás que contás con la autorización del titular para consultar sus datos. Es una declaración TUYA y queda registrada como evidencia. Sin este header la consulta se rechaza con 400 y no se cobra."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/services/verifycol/runt-persona-consultar","host":["{{base_url}}"],"path":["api","v1","gateway","services","verifycol","runt-persona-consultar"]},"description":"RUNT — persona (RUNT). Licencias de conducción, estado del conductor, multas, SICOV, certificados y trámites. Informativa.\n\nCosto: 1 crédito(s).\n\nTipos de documento aceptados: CC, CE, TI, PA, PPT. Cualquier otro se rechaza con 422 y NO cobra créditos.\n\nASÍNCRONO: responde 202 con `task_id` y `status: \"QUEUED\"` (en MAYÚSCULAS). El resultado se recoge sondeando `/api/v1/gateway/services/verifycol/tasks/{task_id}` cada 2-5 s hasta `COMPLETED` o `FAILED`.\n\nRequiere el header `X-Data-Authorization: true` — Ley 1581. Es una declaración TUYA de que contás con la autorización del titular, y queda registrada como evidencia. Sin ella: 400, y no se cobra.\n\nEN EL SANDBOX (key `vf_test_`): el documento del ejemplo (900000003) es un sujeto del banco y responde su escenario, gratis. Con una key live va a la fuente real y se cobra: reemplazalo por el de un titular que te autorizó.","body":{"mode":"raw","raw":"{\n  \"documents\": [\n    {\n      \"tipo_documento\": \"CC\",\n      \"numero_documento\": \"900000003\",\n      \"primer_apellido\": \"VERIFYCOL\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"RUNT Persona - Consulta ciudadano — ejemplo","originalRequest":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"X-Data-Authorization","value":"true","type":"text","description":"Ley 1581: declarás que contás con la autorización del titular para consultar sus datos. Es una declaración TUYA y queda registrada como evidencia. Sin este header la consulta se rechaza con 400 y no se cobra."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/services/verifycol/runt-persona-consultar","host":["{{base_url}}"],"path":["api","v1","gateway","services","verifycol","runt-persona-consultar"]},"description":"RUNT — persona (RUNT). Licencias de conducción, estado del conductor, multas, SICOV, certificados y trámites. Informativa.\n\nCosto: 1 crédito(s).\n\nTipos de documento aceptados: CC, CE, TI, PA, PPT. Cualquier otro se rechaza con 422 y NO cobra créditos.\n\nASÍNCRONO: responde 202 con `task_id` y `status: \"QUEUED\"` (en MAYÚSCULAS). El resultado se recoge sondeando `/api/v1/gateway/services/verifycol/tasks/{task_id}` cada 2-5 s hasta `COMPLETED` o `FAILED`.\n\nRequiere el header `X-Data-Authorization: true` — Ley 1581. Es una declaración TUYA de que contás con la autorización del titular, y queda registrada como evidencia. Sin ella: 400, y no se cobra.\n\nEN EL SANDBOX (key `vf_test_`): el documento del ejemplo (900000003) es un sujeto del banco y responde su escenario, gratis. Con una key live va a la fuente real y se cobra: reemplazalo por el de un titular que te autorizó.","body":{"mode":"raw","raw":"{\n  \"documents\": [\n    {\n      \"tipo_documento\": \"CC\",\n      \"numero_documento\": \"900000003\",\n      \"primer_apellido\": \"VERIFYCOL\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"status":"Accepted","code":202,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"task_id\": \"abc-141\",\n  \"status\": \"QUEUED\",\n  \"total\": 1,\n  \"type\": \"runt_persona\",\n  \"message\": \"1 persona(s) encolada(s) para consulta en RUNT Persona\"\n}"}],"event":[{"listen":"test","script":{"type":"text/javascript","exec":["var sinCaso = pm.response.code === 400 &&","    pm.response.text().indexOf(\"sandbox_sin_caso\") >= 0;","if (sinCaso) {","    console.log(\"El sandbox no tiene escenario para esta fuente con este documento (sandbox_sin_caso): no se evaluó.\");","}","var t = sinCaso ? pm.test.skip : pm.test;","","t(\"La consulta responde 200/202 con el sobre del proxy\", function () {","    pm.expect([200, 202]).to.include(pm.response.code);","    var b = pm.response.json();","    pm.expect(b.success, \"success:false con status 2xx no debería pasar\").to.be.true;","    pm.expect(b).to.have.property(\"data\");","    var tarea = b.data && b.data.task_id;","    pm.expect(tarea, \"sin data.task_id no hay qué sondear\").to.be.a(\"string\");","    // Para `3 · Tareas → Estado y resultado de UNA tarea`.","    pm.collectionVariables.set(\"task_id\", tarea);","});"]}}]},{"name":"SIMIT - Comparendos y multas de tránsito","request":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"X-Data-Authorization","value":"true","type":"text","description":"Ley 1581: declarás que contás con la autorización del titular para consultar sus datos. Es una declaración TUYA y queda registrada como evidencia. Sin este header la consulta se rechaza con 400 y no se cobra."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/services/verifycol/simit-consultar","host":["{{base_url}}"],"path":["api","v1","gateway","services","verifycol","simit-consultar"]},"description":"SIMIT (Federación Colombiana de Municipios). Comparendos, multas, acuerdos de pago y paz y salvo. Informativa.\n\nCosto: 1 crédito(s).\n\nASÍNCRONO: responde 202 con `task_id` y `status: \"QUEUED\"` (en MAYÚSCULAS). El resultado se recoge sondeando `/api/v1/gateway/services/verifycol/tasks/{task_id}` cada 2-5 s hasta `COMPLETED` o `FAILED`.\n\nRequiere el header `X-Data-Authorization: true` — Ley 1581. Es una declaración TUYA de que contás con la autorización del titular, y queda registrada como evidencia. Sin ella: 400, y no se cobra.\n\n⚠ SÓLO CON KEY LIVE. Esta fuente no tiene escenario en el sandbox: con una key de prueba (`vf_test_`) responde 400 `sandbox_sin_caso`, y en un reporte de prueba se omite con `reason: \"not_in_sandbox\"`. Con una key live la consulta va a la fuente real y se cobra: el documento del ejemplo es sintético en el sandbox: no lo uses con una key live; reemplazalo por el de un titular que te autorizó.","body":{"mode":"raw","raw":"{\n  \"documents\": [\n    {\n      \"filtro\": \"900000003\",\n      \"max_detalle\": 1000\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"SIMIT - Comparendos y multas de tránsito — ejemplo","originalRequest":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"X-Data-Authorization","value":"true","type":"text","description":"Ley 1581: declarás que contás con la autorización del titular para consultar sus datos. Es una declaración TUYA y queda registrada como evidencia. Sin este header la consulta se rechaza con 400 y no se cobra."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/services/verifycol/simit-consultar","host":["{{base_url}}"],"path":["api","v1","gateway","services","verifycol","simit-consultar"]},"description":"SIMIT (Federación Colombiana de Municipios). Comparendos, multas, acuerdos de pago y paz y salvo. Informativa.\n\nCosto: 1 crédito(s).\n\nASÍNCRONO: responde 202 con `task_id` y `status: \"QUEUED\"` (en MAYÚSCULAS). El resultado se recoge sondeando `/api/v1/gateway/services/verifycol/tasks/{task_id}` cada 2-5 s hasta `COMPLETED` o `FAILED`.\n\nRequiere el header `X-Data-Authorization: true` — Ley 1581. Es una declaración TUYA de que contás con la autorización del titular, y queda registrada como evidencia. Sin ella: 400, y no se cobra.\n\n⚠ SÓLO CON KEY LIVE. Esta fuente no tiene escenario en el sandbox: con una key de prueba (`vf_test_`) responde 400 `sandbox_sin_caso`, y en un reporte de prueba se omite con `reason: \"not_in_sandbox\"`. Con una key live la consulta va a la fuente real y se cobra: el documento del ejemplo es sintético en el sandbox: no lo uses con una key live; reemplazalo por el de un titular que te autorizó.","body":{"mode":"raw","raw":"{\n  \"documents\": [\n    {\n      \"filtro\": \"900000003\",\n      \"max_detalle\": 1000\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"status":"Accepted","code":202,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"task_id\": \"abc-140\",\n  \"status\": \"QUEUED\",\n  \"total\": 1,\n  \"type\": \"simit\",\n  \"message\": \"1 consulta(s) encolada(s) para SIMIT\"\n}"}],"event":[{"listen":"test","script":{"type":"text/javascript","exec":["var sinCaso = pm.response.code === 400 &&","    pm.response.text().indexOf(\"sandbox_sin_caso\") >= 0;","if (sinCaso) {","    console.log(\"El sandbox no tiene escenario para esta fuente con este documento (sandbox_sin_caso): no se evaluó.\");","}","var t = sinCaso ? pm.test.skip : pm.test;","","t(\"La consulta responde 200/202 con el sobre del proxy\", function () {","    pm.expect([200, 202]).to.include(pm.response.code);","    var b = pm.response.json();","    pm.expect(b.success, \"success:false con status 2xx no debería pasar\").to.be.true;","    pm.expect(b).to.have.property(\"data\");","    var tarea = b.data && b.data.task_id;","    pm.expect(tarea, \"sin data.task_id no hay qué sondear\").to.be.a(\"string\");","    // Para `3 · Tareas → Estado y resultado de UNA tarea`.","    pm.collectionVariables.set(\"task_id\", tarea);","});"]}}]}]},{"name":"Empresas","item":[{"name":"RUES - Registro Único Empresarial y Social","request":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"X-Data-Authorization","value":"true","type":"text","description":"Ley 1581: declarás que contás con la autorización del titular para consultar sus datos. Es una declaración TUYA y queda registrada como evidencia. Sin este header la consulta se rechaza con 400 y no se cobra."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/services/verifycol/rues-consultar","host":["{{base_url}}"],"path":["api","v1","gateway","services","verifycol","rues-consultar"]},"description":"RUES (Confecámaras y cámaras de comercio). Matrícula mercantil y su estado, representación legal, establecimientos, noticias registrales, multas y sanciones, grupos empresariales y RUP. Informativa.\n\nCosto: 1 crédito(s).\n\nASÍNCRONO: responde 202 con `task_id` y `status: \"QUEUED\"` (en MAYÚSCULAS). El resultado se recoge sondeando `/api/v1/gateway/services/verifycol/tasks/{task_id}` cada 2-5 s hasta `COMPLETED` o `FAILED`.\n\nRequiere el header `X-Data-Authorization: true` — Ley 1581. Es una declaración TUYA de que contás con la autorización del titular, y queda registrada como evidencia. Sin ella: 400, y no se cobra.\n\nEN EL SANDBOX (key `vf_test_`): el documento del ejemplo (900000008) es un sujeto del banco y responde su escenario, gratis. Con una key live va a la fuente real y se cobra: reemplazalo por el de un titular que te autorizó.","body":{"mode":"raw","raw":"{\n  \"documents\": [\n    {\n      \"entrada\": \"900000008\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"RUES - Registro Único Empresarial y Social — ejemplo","originalRequest":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"X-Data-Authorization","value":"true","type":"text","description":"Ley 1581: declarás que contás con la autorización del titular para consultar sus datos. Es una declaración TUYA y queda registrada como evidencia. Sin este header la consulta se rechaza con 400 y no se cobra."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/services/verifycol/rues-consultar","host":["{{base_url}}"],"path":["api","v1","gateway","services","verifycol","rues-consultar"]},"description":"RUES (Confecámaras y cámaras de comercio). Matrícula mercantil y su estado, representación legal, establecimientos, noticias registrales, multas y sanciones, grupos empresariales y RUP. Informativa.\n\nCosto: 1 crédito(s).\n\nASÍNCRONO: responde 202 con `task_id` y `status: \"QUEUED\"` (en MAYÚSCULAS). El resultado se recoge sondeando `/api/v1/gateway/services/verifycol/tasks/{task_id}` cada 2-5 s hasta `COMPLETED` o `FAILED`.\n\nRequiere el header `X-Data-Authorization: true` — Ley 1581. Es una declaración TUYA de que contás con la autorización del titular, y queda registrada como evidencia. Sin ella: 400, y no se cobra.\n\nEN EL SANDBOX (key `vf_test_`): el documento del ejemplo (900000008) es un sujeto del banco y responde su escenario, gratis. Con una key live va a la fuente real y se cobra: reemplazalo por el de un titular que te autorizó.","body":{"mode":"raw","raw":"{\n  \"documents\": [\n    {\n      \"entrada\": \"900000008\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"status":"Accepted","code":202,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"task_id\": \"abc-141\",\n  \"status\": \"QUEUED\",\n  \"total\": 1,\n  \"type\": \"rues\",\n  \"message\": \"1 consulta(s) encolada(s) para RUES\"\n}"}],"event":[{"listen":"test","script":{"type":"text/javascript","exec":["var sinCaso = pm.response.code === 400 &&","    pm.response.text().indexOf(\"sandbox_sin_caso\") >= 0;","if (sinCaso) {","    console.log(\"El sandbox no tiene escenario para esta fuente con este documento (sandbox_sin_caso): no se evaluó.\");","}","var t = sinCaso ? pm.test.skip : pm.test;","","t(\"La consulta responde 200/202 con el sobre del proxy\", function () {","    pm.expect([200, 202]).to.include(pm.response.code);","    var b = pm.response.json();","    pm.expect(b.success, \"success:false con status 2xx no debería pasar\").to.be.true;","    pm.expect(b).to.have.property(\"data\");","    var tarea = b.data && b.data.task_id;","    pm.expect(tarea, \"sin data.task_id no hay qué sondear\").to.be.a(\"string\");","    // Para `3 · Tareas → Estado y resultado de UNA tarea`.","    pm.collectionVariables.set(\"task_id\", tarea);","});"]}}]},{"name":"RUT — Datos del PDF del contribuyente","request":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"X-Data-Authorization","value":"true","type":"text","description":"Ley 1581: declarás que contás con la autorización del titular para consultar sus datos. Es una declaración TUYA y queda registrada como evidencia. Sin este header la consulta se rechaza con 400 y no se cobra."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/services/verifycol/rut-pdf-parsear","host":["{{base_url}}"],"path":["api","v1","gateway","services","verifycol","rut-pdf-parsear"]},"description":"RUT — lectura del PDF (DIAN (documento que aporta el titular)). NIT y dígito de verificación, razón social, ubicación, actividades CIIU, responsabilidades y representación legal; lee el código QR y detecta las marcas de agua de suspendido o borrador. Informativa.\n\nCosto: 1 crédito(s).\n\nASÍNCRONO: responde 202 con `task_id` y `status: \"QUEUED\"` (en MAYÚSCULAS). El resultado se recoge sondeando `/api/v1/gateway/services/verifycol/tasks/{task_id}` cada 2-5 s hasta `COMPLETED` o `FAILED`.\n\nRequiere el header `X-Data-Authorization: true` — Ley 1581. Es una declaración TUYA de que contás con la autorización del titular, y queda registrada como evidencia. Sin ella: 400, y no se cobra.\n\n⚠ SÓLO CON KEY LIVE. Esta fuente no tiene escenario en el sandbox: con una key de prueba (`vf_test_`) responde 400 `sandbox_sin_caso`, y en un reporte de prueba se omite con `reason: \"not_in_sandbox\"`. Con una key live la consulta va a la fuente real y se cobra: el documento del ejemplo es sintético en el sandbox: no lo uses con una key live; reemplazalo por el de un titular que te autorizó.","body":{"mode":"raw","raw":"{\n  \"content_base64\": \"JVBERi0xLjQKJSBQREYgc2ludGV0aWNvIGRlIGVqZW1wbG86IG5vIGVzIHVuIFJVVAolJUVPRgo=\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"RUT — Datos del PDF del contribuyente — ejemplo","originalRequest":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"X-Data-Authorization","value":"true","type":"text","description":"Ley 1581: declarás que contás con la autorización del titular para consultar sus datos. Es una declaración TUYA y queda registrada como evidencia. Sin este header la consulta se rechaza con 400 y no se cobra."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/services/verifycol/rut-pdf-parsear","host":["{{base_url}}"],"path":["api","v1","gateway","services","verifycol","rut-pdf-parsear"]},"description":"RUT — lectura del PDF (DIAN (documento que aporta el titular)). NIT y dígito de verificación, razón social, ubicación, actividades CIIU, responsabilidades y representación legal; lee el código QR y detecta las marcas de agua de suspendido o borrador. Informativa.\n\nCosto: 1 crédito(s).\n\nASÍNCRONO: responde 202 con `task_id` y `status: \"QUEUED\"` (en MAYÚSCULAS). El resultado se recoge sondeando `/api/v1/gateway/services/verifycol/tasks/{task_id}` cada 2-5 s hasta `COMPLETED` o `FAILED`.\n\nRequiere el header `X-Data-Authorization: true` — Ley 1581. Es una declaración TUYA de que contás con la autorización del titular, y queda registrada como evidencia. Sin ella: 400, y no se cobra.\n\n⚠ SÓLO CON KEY LIVE. Esta fuente no tiene escenario en el sandbox: con una key de prueba (`vf_test_`) responde 400 `sandbox_sin_caso`, y en un reporte de prueba se omite con `reason: \"not_in_sandbox\"`. Con una key live la consulta va a la fuente real y se cobra: el documento del ejemplo es sintético en el sandbox: no lo uses con una key live; reemplazalo por el de un titular que te autorizó.","body":{"mode":"raw","raw":"{\n  \"content_base64\": \"JVBERi0xLjQKJSBQREYgc2ludGV0aWNvIGRlIGVqZW1wbG86IG5vIGVzIHVuIFJVVAolJUVPRgo=\"\n}","options":{"raw":{"language":"json"}}}},"status":"Accepted","code":202,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"task_id\": \"abc-142\",\n  \"status\": \"QUEUED\",\n  \"total\": 1,\n  \"type\": \"rut_pdf\",\n  \"message\": \"PDF del RUT encolado para extracción\"\n}"}],"event":[{"listen":"test","script":{"type":"text/javascript","exec":["var sinCaso = pm.response.code === 400 &&","    pm.response.text().indexOf(\"sandbox_sin_caso\") >= 0;","if (sinCaso) {","    console.log(\"El sandbox no tiene escenario para esta fuente con este documento (sandbox_sin_caso): no se evaluó.\");","}","var t = sinCaso ? pm.test.skip : pm.test;","","t(\"La consulta responde 200/202 con el sobre del proxy\", function () {","    pm.expect([200, 202]).to.include(pm.response.code);","    var b = pm.response.json();","    pm.expect(b.success, \"success:false con status 2xx no debería pasar\").to.be.true;","    pm.expect(b).to.have.property(\"data\");","    var tarea = b.data && b.data.task_id;","    pm.expect(tarea, \"sin data.task_id no hay qué sondear\").to.be.a(\"string\");","    // Para `3 · Tareas → Estado y resultado de UNA tarea`.","    pm.collectionVariables.set(\"task_id\", tarea);","});"]}}]}]},{"name":"Contratación pública","item":[{"name":"SECOP - Contratación Pública (SECOP I y II)","request":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"X-Data-Authorization","value":"true","type":"text","description":"Ley 1581: declarás que contás con la autorización del titular para consultar sus datos. Es una declaración TUYA y queda registrada como evidencia. Sin este header la consulta se rechaza con 400 y no se cobra."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/services/verifycol/secop-consultar","host":["{{base_url}}"],"path":["api","v1","gateway","services","verifycol","secop-consultar"]},"description":"SECOP I y II (Colombia Compra Eficiente). Contratos con el Estado (como proveedor o representante legal) y multas y sanciones a proveedores, separando las firmes de las pendientes. Informativa.\n\nCosto: 1 crédito(s).\n\nRequiere el header `X-Data-Authorization: true` — Ley 1581. Es una declaración TUYA de que contás con la autorización del titular, y queda registrada como evidencia. Sin ella: 400, y no se cobra.\n\n⚠ SÓLO CON KEY LIVE. Esta fuente no tiene escenario en el sandbox: con una key de prueba (`vf_test_`) responde 400 `sandbox_sin_caso`, y en un reporte de prueba se omite con `reason: \"not_in_sandbox\"`. Con una key live la consulta va a la fuente real y se cobra: el documento del ejemplo es sintético en el sandbox: no lo uses con una key live; reemplazalo por el de un titular que te autorizó.","body":{"mode":"raw","raw":"{\n  \"documento\": \"900000003\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"SECOP - Contratación Pública (SECOP I y II) — ejemplo","originalRequest":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"X-Data-Authorization","value":"true","type":"text","description":"Ley 1581: declarás que contás con la autorización del titular para consultar sus datos. Es una declaración TUYA y queda registrada como evidencia. Sin este header la consulta se rechaza con 400 y no se cobra."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/services/verifycol/secop-consultar","host":["{{base_url}}"],"path":["api","v1","gateway","services","verifycol","secop-consultar"]},"description":"SECOP I y II (Colombia Compra Eficiente). Contratos con el Estado (como proveedor o representante legal) y multas y sanciones a proveedores, separando las firmes de las pendientes. Informativa.\n\nCosto: 1 crédito(s).\n\nRequiere el header `X-Data-Authorization: true` — Ley 1581. Es una declaración TUYA de que contás con la autorización del titular, y queda registrada como evidencia. Sin ella: 400, y no se cobra.\n\n⚠ SÓLO CON KEY LIVE. Esta fuente no tiene escenario en el sandbox: con una key de prueba (`vf_test_`) responde 400 `sandbox_sin_caso`, y en un reporte de prueba se omite con `reason: \"not_in_sandbox\"`. Con una key live la consulta va a la fuente real y se cobra: el documento del ejemplo es sintético en el sandbox: no lo uses con una key live; reemplazalo por el de un titular que te autorizó.","body":{"mode":"raw","raw":"{\n  \"documento\": \"900000003\"\n}","options":{"raw":{"language":"json"}}}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"sin_hallazgos\",\n  \"contratos\": [],\n  \"sanciones\": [],\n  \"sanciones_pendientes\": [],\n  \"error_detail\": null,\n  \"error_code\": null,\n  \"retry_after_s\": null,\n  \"truncado\": {\n    \"contratos\": false,\n    \"contratos_i\": false,\n    \"sanciones\": false,\n    \"contratos_ii_ids\": false\n  },\n  \"max_filas\": {\n    \"contratos\": 500,\n    \"sanciones\": 3000,\n    \"contratos_ii_ids\": 5000\n  },\n  \"completo\": true,\n  \"tramos\": {\n    \"contratos_ii\": \"ok\",\n    \"contratos_ii_ids\": \"no_intentado\",\n    \"contratos_i\": \"ok\",\n    \"contratos_i_historico\": \"ok\",\n    \"sanciones_ii\": \"ok\",\n    \"sanciones_i\": \"ok\"\n  },\n  \"consulted_at\": \"2026-09-21T14:03:11.482913+00:00\",\n  \"elapsed_ms\": 780\n}"}],"event":[{"listen":"test","script":{"type":"text/javascript","exec":["var sinCaso = pm.response.code === 400 &&","    pm.response.text().indexOf(\"sandbox_sin_caso\") >= 0;","if (sinCaso) {","    console.log(\"El sandbox no tiene escenario para esta fuente con este documento (sandbox_sin_caso): no se evaluó.\");","}","var t = sinCaso ? pm.test.skip : pm.test;","","t(\"La consulta responde 200/202 con el sobre del proxy\", function () {","    pm.expect([200, 202]).to.include(pm.response.code);","    var b = pm.response.json();","    pm.expect(b.success, \"success:false con status 2xx no debería pasar\").to.be.true;","    pm.expect(b).to.have.property(\"data\");","});"]}}]}]},{"name":"Formación","item":[{"name":"SENA — Certificados de formación","request":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"X-Data-Authorization","value":"true","type":"text","description":"Ley 1581: declarás que contás con la autorización del titular para consultar sus datos. Es una declaración TUYA y queda registrada como evidencia. Sin este header la consulta se rechaza con 400 y no se cobra."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/services/verifycol/sena-certificados","host":["{{base_url}}"],"path":["api","v1","gateway","services","verifycol","sena-certificados"]},"description":"SENA — certificados de formación (Servicio Nacional de Aprendizaje (SENA)). Certificados de formación registrados: tipo, programa, nivel y fechas. Con `descargar_pdfs`, además los datos de cada certificado oficial y si el nombre y el documento impresos coinciden con los consultados. El resultado queda disponible 24 h. Informativa.\n\nCosto: 1 crédito(s).\n\nTipos de documento aceptados: CC, CE, TI, PA, PPT. Cualquier otro se rechaza con 422 y NO cobra créditos.\n\nASÍNCRONO: responde 202 con `task_id` y `status: \"QUEUED\"` (en MAYÚSCULAS). El resultado se recoge sondeando `/api/v1/gateway/services/verifycol/tasks/{task_id}` cada 2-5 s hasta `COMPLETED` o `FAILED`.\n\nRequiere el header `X-Data-Authorization: true` — Ley 1581. Es una declaración TUYA de que contás con la autorización del titular, y queda registrada como evidencia. Sin ella: 400, y no se cobra.\n\n⚠ SÓLO CON KEY LIVE. Esta fuente no tiene escenario en el sandbox: con una key de prueba (`vf_test_`) responde 400 `sandbox_sin_caso`, y en un reporte de prueba se omite con `reason: \"not_in_sandbox\"`. Con una key live la consulta va a la fuente real y se cobra: el documento del ejemplo es sintético en el sandbox: no lo uses con una key live; reemplazalo por el de un titular que te autorizó.","body":{"mode":"raw","raw":"{\n  \"documents\": [\n    {\n      \"tipo_documento\": \"CC\",\n      \"numero_documento\": \"900000003\",\n      \"descargar_pdfs\": false\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"SENA — Certificados de formación — ejemplo","originalRequest":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"X-Data-Authorization","value":"true","type":"text","description":"Ley 1581: declarás que contás con la autorización del titular para consultar sus datos. Es una declaración TUYA y queda registrada como evidencia. Sin este header la consulta se rechaza con 400 y no se cobra."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/services/verifycol/sena-certificados","host":["{{base_url}}"],"path":["api","v1","gateway","services","verifycol","sena-certificados"]},"description":"SENA — certificados de formación (Servicio Nacional de Aprendizaje (SENA)). Certificados de formación registrados: tipo, programa, nivel y fechas. Con `descargar_pdfs`, además los datos de cada certificado oficial y si el nombre y el documento impresos coinciden con los consultados. El resultado queda disponible 24 h. Informativa.\n\nCosto: 1 crédito(s).\n\nTipos de documento aceptados: CC, CE, TI, PA, PPT. Cualquier otro se rechaza con 422 y NO cobra créditos.\n\nASÍNCRONO: responde 202 con `task_id` y `status: \"QUEUED\"` (en MAYÚSCULAS). El resultado se recoge sondeando `/api/v1/gateway/services/verifycol/tasks/{task_id}` cada 2-5 s hasta `COMPLETED` o `FAILED`.\n\nRequiere el header `X-Data-Authorization: true` — Ley 1581. Es una declaración TUYA de que contás con la autorización del titular, y queda registrada como evidencia. Sin ella: 400, y no se cobra.\n\n⚠ SÓLO CON KEY LIVE. Esta fuente no tiene escenario en el sandbox: con una key de prueba (`vf_test_`) responde 400 `sandbox_sin_caso`, y en un reporte de prueba se omite con `reason: \"not_in_sandbox\"`. Con una key live la consulta va a la fuente real y se cobra: el documento del ejemplo es sintético en el sandbox: no lo uses con una key live; reemplazalo por el de un titular que te autorizó.","body":{"mode":"raw","raw":"{\n  \"documents\": [\n    {\n      \"tipo_documento\": \"CC\",\n      \"numero_documento\": \"900000003\",\n      \"descargar_pdfs\": false\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"status":"Accepted","code":202,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"task_id\": \"abc-143\",\n  \"status\": \"QUEUED\",\n  \"total\": 1,\n  \"type\": \"sena\",\n  \"message\": \"Consulta de certificados SENA encolada\"\n}"}],"event":[{"listen":"test","script":{"type":"text/javascript","exec":["var sinCaso = pm.response.code === 400 &&","    pm.response.text().indexOf(\"sandbox_sin_caso\") >= 0;","if (sinCaso) {","    console.log(\"El sandbox no tiene escenario para esta fuente con este documento (sandbox_sin_caso): no se evaluó.\");","}","var t = sinCaso ? pm.test.skip : pm.test;","","t(\"La consulta responde 200/202 con el sobre del proxy\", function () {","    pm.expect([200, 202]).to.include(pm.response.code);","    var b = pm.response.json();","    pm.expect(b.success, \"success:false con status 2xx no debería pasar\").to.be.true;","    pm.expect(b).to.have.property(\"data\");","    var tarea = b.data && b.data.task_id;","    pm.expect(tarea, \"sin data.task_id no hay qué sondear\").to.be.a(\"string\");","    // Para `3 · Tareas → Estado y resultado de UNA tarea`.","    pm.collectionVariables.set(\"task_id\", tarea);","});"]}}]}]},{"name":"Catálogos","item":[{"name":"Catálogo - Cargos","request":{"method":"GET","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/services/verifycol/catalog-positions","host":["{{base_url}}"],"path":["api","v1","gateway","services","verifycol","catalog-positions"]},"description":"Los cargos que acepta `procuraduria-especial` en `cargo` (`?system_id=`): se envía su `external_code`. No cobra.\n\nCosto: 0 crédito(s).\n\nEn el sandbox (key `vf_test_`) los catálogos no se sirven: responden 400 `sandbox_sin_caso`. Con una key live no consultan datos de nadie."},"response":[{"name":"Catálogo - Cargos — ejemplo","originalRequest":{"method":"GET","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/services/verifycol/catalog-positions","host":["{{base_url}}"],"path":["api","v1","gateway","services","verifycol","catalog-positions"]},"description":"Los cargos que acepta `procuraduria-especial` en `cargo` (`?system_id=`): se envía su `external_code`. No cobra.\n\nCosto: 0 crédito(s).\n\nEn el sandbox (key `vf_test_`) los catálogos no se sirven: responden 400 `sandbox_sin_caso`. Con una key live no consultan datos de nadie."},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"system_id\": \"9a1c2d3e-4f5b-6789-abcd-ef0123456789\",\n  \"positions\": [\n    {\n      \"external_code\": \"ALM\",\n      \"name\": \"Alcalde Municipal\"\n    }\n  ],\n  \"total\": 20\n}"}],"event":[{"listen":"test","script":{"type":"text/javascript","exec":["var sinCaso = pm.response.code === 400 &&","    pm.response.text().indexOf(\"sandbox_sin_caso\") >= 0;","if (sinCaso) {","    console.log(\"El sandbox no tiene escenario para esta fuente con este documento (sandbox_sin_caso): no se evaluó.\");","}","var t = sinCaso ? pm.test.skip : pm.test;","","t(\"La consulta responde 200/202 con el sobre del proxy\", function () {","    pm.expect([200, 202]).to.include(pm.response.code);","    var b = pm.response.json();","    pm.expect(b.success, \"success:false con status 2xx no debería pasar\").to.be.true;","    pm.expect(b).to.have.property(\"data\");","});"]}}]},{"name":"Catálogo - Sistemas","request":{"method":"GET","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/services/verifycol/catalog-systems","host":["{{base_url}}"],"path":["api","v1","gateway","services","verifycol","catalog-systems"]},"description":"Los sistemas del catálogo: devuelve el `system_id` que piden los demás catálogos. No cobra.\n\nCosto: 0 crédito(s).\n\nEn el sandbox (key `vf_test_`) los catálogos no se sirven: responden 400 `sandbox_sin_caso`. Con una key live no consultan datos de nadie."},"response":[{"name":"Catálogo - Sistemas — ejemplo","originalRequest":{"method":"GET","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/services/verifycol/catalog-systems","host":["{{base_url}}"],"path":["api","v1","gateway","services","verifycol","catalog-systems"]},"description":"Los sistemas del catálogo: devuelve el `system_id` que piden los demás catálogos. No cobra.\n\nCosto: 0 crédito(s).\n\nEn el sandbox (key `vf_test_`) los catálogos no se sirven: responden 400 `sandbox_sin_caso`. Con una key live no consultan datos de nadie."},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"systems\": [\n    {\n      \"id\": \"e4c1b2a9-1234-5678-90ab-cdef12345678\",\n      \"system_name\": \"Contraloría Persona Natural\"\n    }\n  ],\n  \"total\": 6\n}"}],"event":[{"listen":"test","script":{"type":"text/javascript","exec":["var sinCaso = pm.response.code === 400 &&","    pm.response.text().indexOf(\"sandbox_sin_caso\") >= 0;","if (sinCaso) {","    console.log(\"El sandbox no tiene escenario para esta fuente con este documento (sandbox_sin_caso): no se evaluó.\");","}","var t = sinCaso ? pm.test.skip : pm.test;","","t(\"La consulta responde 200/202 con el sobre del proxy\", function () {","    pm.expect([200, 202]).to.include(pm.response.code);","    var b = pm.response.json();","    pm.expect(b.success, \"success:false con status 2xx no debería pasar\").to.be.true;","    pm.expect(b).to.have.property(\"data\");","});"]}}]},{"name":"Catálogo - Tipos de Documento","request":{"method":"GET","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/services/verifycol/catalog-document-types","host":["{{base_url}}"],"path":["api","v1","gateway","services","verifycol","catalog-document-types"]},"description":"Los tipos de documento que acepta un sistema (`?system_id=`). No cobra.\n\nCosto: 0 crédito(s).\n\nEn el sandbox (key `vf_test_`) los catálogos no se sirven: responden 400 `sandbox_sin_caso`. Con una key live no consultan datos de nadie."},"response":[{"name":"Catálogo - Tipos de Documento — ejemplo","originalRequest":{"method":"GET","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/services/verifycol/catalog-document-types","host":["{{base_url}}"],"path":["api","v1","gateway","services","verifycol","catalog-document-types"]},"description":"Los tipos de documento que acepta un sistema (`?system_id=`). No cobra.\n\nCosto: 0 crédito(s).\n\nEn el sandbox (key `vf_test_`) los catálogos no se sirven: responden 400 `sandbox_sin_caso`. Con una key live no consultan datos de nadie."},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"system_id\": \"e4c1b2a9-1234-5678-90ab-cdef12345678\",\n  \"document_types\": [\n    {\n      \"standard_code\": \"CC\",\n      \"name\": \"Cédula de Ciudadanía\"\n    }\n  ],\n  \"total\": 5\n}"}],"event":[{"listen":"test","script":{"type":"text/javascript","exec":["var sinCaso = pm.response.code === 400 &&","    pm.response.text().indexOf(\"sandbox_sin_caso\") >= 0;","if (sinCaso) {","    console.log(\"El sandbox no tiene escenario para esta fuente con este documento (sandbox_sin_caso): no se evaluó.\");","}","var t = sinCaso ? pm.test.skip : pm.test;","","t(\"La consulta responde 200/202 con el sobre del proxy\", function () {","    pm.expect([200, 202]).to.include(pm.response.code);","    var b = pm.response.json();","    pm.expect(b.success, \"success:false con status 2xx no debería pasar\").to.be.true;","    pm.expect(b).to.have.property(\"data\");","});"]}}]}]}],"description":"Una fuente puntual, cuando no querés el reporte completo.\n\nEN EL SANDBOX (key `vf_test_` en `api_key`) responden sólo las fuentes con escenario en el banco: `adres-afiliados-compensados`, `australia-dfat-search`, `canada-osfi-search`, `contraloria-juridica`, `contraloria-natural`, `eu-sanctions-search`, `interpol-search`, `ofac-search`, `onu-search`, `pep-search`, `policia-antecedentes`, `policia-medidas-correctivas`, `procuraduria-ordinario`, `rues-consultar`, `runt-persona-consultar`, `swiss-seco-search`, `uk-ofsi-search`, `worldbank-debarred-search`. Cada request de esta carpeta ya manda un sujeto del banco que tiene escenario para su fuente. Las demás están marcadas «SÓLO CON KEY LIVE»: con una key de prueba responden 400 `sandbox_sin_caso`, y en un reporte de prueba se omiten con `reason: \"not_in_sandbox\"`.\n\nCon una key live cada consulta va a la fuente real y se cobra: reemplazá el documento sintético por el de un titular que te autorizó."},{"name":"3 · Tareas (polling de los asíncronos)","item":[{"name":"Estado y resultado de UNA tarea","request":{"method":"GET","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/services/verifycol/tasks/{{task_id}}","host":["{{base_url}}"],"path":["api","v1","gateway","services","verifycol","tasks","{{task_id}}"]},"description":"El endpoint que trae `results`, y el más importante del canal si usás las fuentes por separado.\n\nSondear cada 2-5 s hasta que `status` sea `COMPLETED` o `FAILED` — SIEMPRE en MAYÚSCULAS. Los estados son `QUEUED`, `PROCESSING`, `COMPLETED`, `FAILED` y `REVOKED`.\n\n`successful` distingue \"terminó\" de \"salió bien\": una tarea puede llegar a `COMPLETED` con documentos fallidos adentro."},"response":[{"name":"Estado y resultado de UNA tarea — ejemplo","originalRequest":{"method":"GET","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/services/verifycol/tasks/{{task_id}}","host":["{{base_url}}"],"path":["api","v1","gateway","services","verifycol","tasks","{{task_id}}"]},"description":"El endpoint que trae `results`, y el más importante del canal si usás las fuentes por separado.\n\nSondear cada 2-5 s hasta que `status` sea `COMPLETED` o `FAILED` — SIEMPRE en MAYÚSCULAS. Los estados son `QUEUED`, `PROCESSING`, `COMPLETED`, `FAILED` y `REVOKED`.\n\n`successful` distingue \"terminó\" de \"salió bien\": una tarea puede llegar a `COMPLETED` con documentos fallidos adentro."},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"status_code\": 200,\n  \"data\": {\n    \"task_id\": \"f8e1a2b3-4c5d-6789-abcd-ef0123456789\",\n    \"status\": \"COMPLETED\",\n    \"type\": \"policia\",\n    \"successful\": true,\n    \"created_at\": \"2026-08-26T04:15:22Z\",\n    \"completed_at\": \"2026-08-26T04:15:58Z\",\n    \"progress\": {\n      \"total\": 1,\n      \"completed\": 1,\n      \"successful\": 1,\n      \"failed\": 0,\n      \"pending\": 0\n    },\n    \"results\": [\n      {\n        \"kind\": \"policia\",\n        \"subject\": {\n          \"tipo_documento\": \"CC\",\n          \"numero_documento\": \"900000003\"\n        },\n        \"has_records\": false,\n        \"consulted_at\": \"2026-08-26T04:15:57Z\"\n      }\n    ]\n  }\n}"}],"event":[{"listen":"prerequest","script":{"type":"text/javascript","exec":["if (!pm.variables.get(\"task_id\")) {","    console.warn(\"Falta la variable `task_id`: este request no se mandó.\");","    pm.execution.skipRequest();","}"]}},{"listen":"test","script":{"type":"text/javascript","exec":["var sinCaso = pm.response.code === 400 &&","    pm.response.text().indexOf(\"sandbox_sin_caso\") >= 0;","if (sinCaso) {","    console.log(\"El sandbox no tiene escenario para esta fuente con este documento (sandbox_sin_caso): no se evaluó.\");","}","var t = sinCaso ? pm.test.skip : pm.test;","t(\"La tarea responde 200 con su estado en MAYÚSCULAS\", function () {","    pm.response.to.have.status(200);","    var d = pm.response.json().data;","    pm.expect(d.task_id).to.eql(pm.variables.get(\"task_id\"));","    pm.expect(d.status).to.be.oneOf([\"QUEUED\", \"PROCESSING\", \"COMPLETED\", \"FAILED\", \"REVOKED\"]);","});"]}}]},{"name":"Listar tareas de la organización","request":{"method":"GET","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/services/verifycol/tasks-list","host":["{{base_url}}"],"path":["api","v1","gateway","services","verifycol","tasks-list"]},"description":"Las últimas tareas de tu organización (máx. 500). NO lleva `task_id`: para una tarea puntual, usá el request de arriba."},"response":[{"name":"Listar tareas de la organización — ejemplo","originalRequest":{"method":"GET","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/services/verifycol/tasks-list","host":["{{base_url}}"],"path":["api","v1","gateway","services","verifycol","tasks-list"]},"description":"Las últimas tareas de tu organización (máx. 500). NO lleva `task_id`: para una tarea puntual, usá el request de arriba."},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"status_code\": 200,\n  \"data\": {\n    \"tasks\": [\n      {\n        \"task_id\": \"f8e1a2b3-4c5d-6789-abcd-ef0123456789\",\n        \"status\": \"COMPLETED\",\n        \"type\": \"policia\",\n        \"successful\": true,\n        \"created_at\": \"2026-08-26T04:15:22Z\",\n        \"completed_at\": \"2026-08-26T04:15:58Z\",\n        \"progress\": {\n          \"total\": 1,\n          \"completed\": 1,\n          \"successful\": 1,\n          \"failed\": 0,\n          \"pending\": 0\n        },\n        \"results\": [\n          {\n            \"kind\": \"policia\",\n            \"subject\": {\n              \"tipo_documento\": \"CC\",\n              \"numero_documento\": \"900000003\"\n            },\n            \"has_records\": false,\n            \"consulted_at\": \"2026-08-26T04:15:57Z\"\n          }\n        ]\n      }\n    ],\n    \"total\": 1\n  }\n}"}],"event":[{"listen":"test","script":{"type":"text/javascript","exec":["var sinCaso = pm.response.code === 400 &&","    pm.response.text().indexOf(\"sandbox_sin_caso\") >= 0;","if (sinCaso) {","    console.log(\"El sandbox no tiene escenario para esta fuente con este documento (sandbox_sin_caso): no se evaluó.\");","}","var t = sinCaso ? pm.test.skip : pm.test;","t(\"El listado responde 200 con las tareas\", function () {","    pm.response.to.have.status(200);","    pm.expect(pm.response.json().data.tasks).to.be.an(\"array\");","});"]}}]}],"description":"Las consultas por fuente son asíncronas: responden 202 con un `task_id` y el resultado se recoge acá. La consulta de la carpeta 2 deja el `task_id` en la variable de la colección."},{"name":"4 · Certificación de idempotencia","item":[{"name":"1. Replay — misma clave, mismo cuerpo → mismo id","request":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"Idempotency-Key","value":"{{cert_key}}","type":"text","description":"Identifica ESTA solicitud. Un reintento por timeout de red con la misma clave devuelve el reporte original —con el header `Idempotent-Replayed: true`— en vez de crear y cobrar otro. Ventana: 24 h. `{{$guid}}` genera una clave nueva en cada envío, que es lo correcto para una solicitud nueva."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/reports/","host":["{{base_url}}"],"path":["api","v1","gateway","api","reports"]},"description":"Crea un reporte con una clave nueva y REINTENTA con la misma clave y el mismo cuerpo, que es lo que hace un cliente cuya conexión se cortó antes de recibir la respuesta.\n\nEl replay devuelve el estado ACTUAL del reporte, no una copia cacheada: si entre las dos llamadas pasó de `processing` a `completed`, vas a ver `completed`. Lo que no cambia es el `id`.\n\nQUÉ TIENE QUE PASAR: 201 con el MISMO `id` y el header `Idempotent-Replayed: true`. No se crea ni se cobra un segundo reporte.\n\nTipos de documento aceptados: CC, CE, NIT, PA.","body":{"mode":"raw","raw":"{\n  \"tipo_documento\": \"CC\",\n  \"numero_documento\": \"900000003\",\n  \"selected_endpoints\": [\n    \"contraloria-natural\"\n  ],\n  \"data_authorization_declared\": true\n}","options":{"raw":{"language":"json"}}}},"id":"cert-replay","event":[{"listen":"prerequest","script":{"type":"text/javascript","exec":["// Clave nueva en cada corrida: con una fija, la segunda corrida","// recibiría el reporte de la primera y el caso no probaría nada.","pm.collectionVariables.set(\"cert_key\", pm.variables.replaceIn(\"{{$guid}}\"));"]}},{"listen":"test","script":{"type":"text/javascript","exec":["function reenviar(clave, cuerpo, cb) {","    pm.sendRequest({","        url: pm.variables.replaceIn(\"{{base_url}}/api/v1/gateway/api/reports/\"),","        method: \"POST\",","        header: {","            \"X-API-KEY\": pm.variables.replaceIn(\"{{api_key}}\"),","            \"Content-Type\": \"application/json\",","            \"Idempotency-Key\": clave","        },","        body: { mode: \"raw\", raw: cuerpo }","    }, cb);","}","","pm.test(\"La creación original responde 201 y NO trae Idempotent-Replayed\", function () {","    pm.response.to.have.status(201);","    pm.expect(pm.response.headers.has(\"Idempotent-Replayed\"),","        \"el original no puede anunciarse como replay\").to.be.false;","});","","pm.test(\"El reintento con la MISMA clave devuelve el MISMO id, con Idempotent-Replayed: true\", function (done) {","    var original = pm.response.json();","    reenviar(pm.collectionVariables.get(\"cert_key\"), pm.request.body.raw, function (err, res) {","        pm.expect(err).to.equal(null);","        pm.expect(res.code, \"un replay sigue siendo 201\").to.eql(201);","        pm.expect(res.json().id,","            \"el reintento creó un reporte NUEVO: se cobró dos veces\").to.eql(original.id);","        pm.expect(res.headers.has(\"Idempotent-Replayed\"),","            \"sin el header, el replay no es demostrable: los dos son 201\").to.be.true;","        done();","    });","});"]}}],"response":[{"name":"1. Replay — misma clave, mismo cuerpo → mismo id — ejemplo","originalRequest":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"Idempotency-Key","value":"{{cert_key}}","type":"text","description":"Identifica ESTA solicitud. Un reintento por timeout de red con la misma clave devuelve el reporte original —con el header `Idempotent-Replayed: true`— en vez de crear y cobrar otro. Ventana: 24 h. `{{$guid}}` genera una clave nueva en cada envío, que es lo correcto para una solicitud nueva."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/reports/","host":["{{base_url}}"],"path":["api","v1","gateway","api","reports"]},"description":"Crea un reporte con una clave nueva y REINTENTA con la misma clave y el mismo cuerpo, que es lo que hace un cliente cuya conexión se cortó antes de recibir la respuesta.\n\nEl replay devuelve el estado ACTUAL del reporte, no una copia cacheada: si entre las dos llamadas pasó de `processing` a `completed`, vas a ver `completed`. Lo que no cambia es el `id`.\n\nQUÉ TIENE QUE PASAR: 201 con el MISMO `id` y el header `Idempotent-Replayed: true`. No se crea ni se cobra un segundo reporte.\n\nTipos de documento aceptados: CC, CE, NIT, PA.","body":{"mode":"raw","raw":"{\n  \"tipo_documento\": \"CC\",\n  \"numero_documento\": \"900000003\",\n  \"selected_endpoints\": [\n    \"contraloria-natural\"\n  ],\n  \"data_authorization_declared\": true\n}","options":{"raw":{"language":"json"}}}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": \"3f2a8c10-5b7e-4d21-9a44-1c8e6b0d5f93\",\n  \"status\": \"processing\",\n  \"overall_status\": null,\n  \"subject_document_type\": \"CC\",\n  \"subject_document_number\": \"900000003\",\n  \"subject_full_name\": null,\n  \"total_sources\": 1,\n  \"completed_sources\": 0,\n  \"successful_sources\": 0,\n  \"failed_sources\": 0,\n  \"sources\": [],\n  \"total_credits_charged\": 1,\n  \"credits_reserved\": 1,\n  \"credits_refunded\": 0,\n  \"omitted_sources\": [],\n  \"omitted_sources_count\": 0,\n  \"has_pdf\": false,\n  \"pdf_generated_at\": null,\n  \"created_at\": \"2026-09-02T14:05:11Z\",\n  \"completed_at\": null,\n  \"deduplicated\": false,\n  \"origin\": null,\n  \"environment\": \"live\",\n  \"test_mode\": false,\n  \"external_reference\": null,\n  \"correlation_id\": null,\n  \"informational_only\": false,\n  \"informational_sources\": 0,\n  \"conclusive_sources\": 0,\n  \"coverage_sufficient\": false,\n  \"covered_dimensions\": [],\n  \"uncovered_dimensions\": [],\n  \"uncovered_coverage_groups\": [],\n  \"narrative_status\": \"none\",\n  \"risk_analysis\": null,\n  \"risk_narrative\": null,\n  \"narrative_generated_at\": null\n}"}]},{"name":"2. Conflicto — misma clave, cuerpo distinto → 409","request":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"Idempotency-Key","value":"{{cert_key_conflicto}}","type":"text","description":"Identifica ESTA solicitud. Un reintento por timeout de red con la misma clave devuelve el reporte original —con el header `Idempotent-Replayed: true`— en vez de crear y cobrar otro. Ventana: 24 h. `{{$guid}}` genera una clave nueva en cada envío, que es lo correcto para una solicitud nueva."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/reports/","host":["{{base_url}}"],"path":["api","v1","gateway","api","reports"]},"description":"Crea un reporte y reintenta con la MISMA clave pero OTRO sujeto.\n\nSe rechaza en vez de devolver el original: la clave identifica UNA solicitud, así que reusarla con otro contenido devolvería el reporte de otra persona.\n\nQUÉ TIENE QUE PASAR: 409 con `error.code: CONFLICT` y `error.reason: IDEMPOTENCY_CONFLICT`, y SIN `Retry-After`: esperar no lo resuelve, hay que emitir una clave nueva.\n\nTipos de documento aceptados: CC, CE, NIT, PA.","body":{"mode":"raw","raw":"{\n  \"tipo_documento\": \"CC\",\n  \"numero_documento\": \"900000003\",\n  \"selected_endpoints\": [\n    \"contraloria-natural\"\n  ],\n  \"data_authorization_declared\": true\n}","options":{"raw":{"language":"json"}}}},"id":"cert-conflicto","event":[{"listen":"prerequest","script":{"type":"text/javascript","exec":["pm.collectionVariables.set(\"cert_key_conflicto\", pm.variables.replaceIn(\"{{$guid}}\"));"]}},{"listen":"test","script":{"type":"text/javascript","exec":["function reenviar(clave, cuerpo, cb) {","    pm.sendRequest({","        url: pm.variables.replaceIn(\"{{base_url}}/api/v1/gateway/api/reports/\"),","        method: \"POST\",","        header: {","            \"X-API-KEY\": pm.variables.replaceIn(\"{{api_key}}\"),","            \"Content-Type\": \"application/json\",","            \"Idempotency-Key\": clave","        },","        body: { mode: \"raw\", raw: cuerpo }","    }, cb);","}","","pm.test(\"La creación original responde 201\", function () {","    pm.response.to.have.status(201);","});","","pm.test(\"La MISMA clave con un cuerpo DISTINTO responde 409 CONFLICT / IDEMPOTENCY_CONFLICT\", function (done) {","    var otro = JSON.parse(pm.request.body.raw);","    otro.numero_documento = \"900000007\";  // otro sujeto = otra solicitud","    reenviar(pm.collectionVariables.get(\"cert_key_conflicto\"), JSON.stringify(otro), function (err, res) {","        pm.expect(err).to.equal(null);","        pm.expect(res.code, \"reusar la clave con otro cuerpo tiene que ser 409\").to.eql(409);","        var e = res.json().error;","        pm.expect(e.code).to.eql(\"CONFLICT\");","        pm.expect(e.reason,","            \"sin `reason` el integrador no sabe si esperar o cambiar la clave\").to.eql(\"IDEMPOTENCY_CONFLICT\");","        pm.expect(res.headers.has(\"Retry-After\"),","            \"este 409 no se resuelve esperando: no puede traer Retry-After\").to.be.false;","        done();","    });","});"]}}],"response":[{"name":"2. Conflicto — misma clave, cuerpo distinto → 409 — ejemplo","originalRequest":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"Idempotency-Key","value":"{{cert_key_conflicto}}","type":"text","description":"Identifica ESTA solicitud. Un reintento por timeout de red con la misma clave devuelve el reporte original —con el header `Idempotent-Replayed: true`— en vez de crear y cobrar otro. Ventana: 24 h. `{{$guid}}` genera una clave nueva en cada envío, que es lo correcto para una solicitud nueva."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/reports/","host":["{{base_url}}"],"path":["api","v1","gateway","api","reports"]},"description":"Crea un reporte y reintenta con la MISMA clave pero OTRO sujeto.\n\nSe rechaza en vez de devolver el original: la clave identifica UNA solicitud, así que reusarla con otro contenido devolvería el reporte de otra persona.\n\nQUÉ TIENE QUE PASAR: 409 con `error.code: CONFLICT` y `error.reason: IDEMPOTENCY_CONFLICT`, y SIN `Retry-After`: esperar no lo resuelve, hay que emitir una clave nueva.\n\nTipos de documento aceptados: CC, CE, NIT, PA.","body":{"mode":"raw","raw":"{\n  \"tipo_documento\": \"CC\",\n  \"numero_documento\": \"900000003\",\n  \"selected_endpoints\": [\n    \"contraloria-natural\"\n  ],\n  \"data_authorization_declared\": true\n}","options":{"raw":{"language":"json"}}}},"status":"Conflict","code":409,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"detail\": \"Este Idempotency-Key ya se usó en las últimas 24 horas con un cuerpo distinto. Genere una clave nueva (UUID) por cada solicitud distinta.\",\n  \"success\": false,\n  \"error\": {\n    \"code\": \"CONFLICT\",\n    \"message\": \"Este Idempotency-Key ya se usó en las últimas 24 horas con un cuerpo distinto. Genere una clave nueva (UUID) por cada solicitud distinta.\",\n    \"reason\": \"IDEMPOTENCY_CONFLICT\"\n  }\n}"}]},{"name":"3. En curso — misma clave mientras la primera corre → 409 con Retry-After","request":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"Idempotency-Key","value":"{{cert_key_curso}}","type":"text","description":"Identifica ESTA solicitud. Un reintento por timeout de red con la misma clave devuelve el reporte original —con el header `Idempotent-Replayed: true`— en vez de crear y cobrar otro. Ventana: 24 h. `{{$guid}}` genera una clave nueva en cada envío, que es lo correcto para una solicitud nueva."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/reports/","host":["{{base_url}}"],"path":["api","v1","gateway","api","reports"]},"description":"Después de crear este reporte, el script de test dispara una RÁFAGA: varias creaciones a la vez con una clave NUEVA, todas con la misma. La primera que llega crea; las otras llegan con ésa todavía corriendo. Es la ráfaga real, no una simulación.\n\nCada llamada de la ráfaga tiene dos desenlaces legítimos y los dos se afirman: 409 en curso con `Retry-After` (lo esperable, porque crear un reporte tarda) o el replay —201 con `Idempotent-Replayed: true` y el MISMO `id`— si la primera cerró antes. Lo que NUNCA puede salir son dos 201 sin `Idempotent-Replayed` o dos `id` distintos: eso serían dos reportes y dos cobros.\n\nSi en una corrida todas cerraron antes (no se vio ningún 409), la consola lo avisa: volvé a mandarlo.\n\nQUÉ TIENE QUE PASAR: 409 con `error.reason: IDEMPOTENCY_IN_PROGRESS` y `Retry-After`. Se reintenta con LA MISMA clave. Si la primera alcanzó a terminar, la respuesta es el replay (201 + `Idempotent-Replayed: true`) — nunca un reporte nuevo.\n\nTipos de documento aceptados: CC, CE, NIT, PA.","body":{"mode":"raw","raw":"{\n  \"tipo_documento\": \"CC\",\n  \"numero_documento\": \"900000003\",\n  \"selected_endpoints\": [\n    \"contraloria-natural\"\n  ],\n  \"data_authorization_declared\": true\n}","options":{"raw":{"language":"json"}}}},"id":"cert-en-curso","event":[{"listen":"prerequest","script":{"type":"text/javascript","exec":["// La ráfaga NO sale de acá: newman espera los sendRequest del","// pre-request antes de mandar el request, y la ráfaga llegaría","// siempre con la primera ya cerrada. Sale del script de test.","pm.collectionVariables.set(\"cert_key_curso\", pm.variables.replaceIn(\"{{$guid}}\"));"]}},{"listen":"test","script":{"type":"text/javascript","exec":["function reenviar(clave, cuerpo, cb) {","    pm.sendRequest({","        url: pm.variables.replaceIn(\"{{base_url}}/api/v1/gateway/api/reports/\"),","        method: \"POST\",","        header: {","            \"X-API-KEY\": pm.variables.replaceIn(\"{{api_key}}\"),","            \"Content-Type\": \"application/json\",","            \"Idempotency-Key\": clave","        },","        body: { mode: \"raw\", raw: cuerpo }","    }, cb);","}","","pm.test(\"La creación original responde 201\", function () {","    pm.response.to.have.status(201);","});","","// Varias creaciones CONCURRENTES con la misma clave nueva: se","// disparan todas sin esperar a ninguna.","var RAFAGA = 3;","pm.test(\"Una ráfaga con la misma clave nunca crea dos reportes (y cada 409 es IN_PROGRESS con Retry-After)\", function (done) {","    var clave = pm.variables.replaceIn(\"{{$guid}}\");","    var cuerpo = pm.request.body.raw;","    var vistas = [];","    function cerrar() {","        if (vistas.length < RAFAGA) { return; }","        var ids = {};","        var originales = 0;","        var enCurso = 0;","        vistas.forEach(function (v) {","            pm.expect(v.err).to.equal(null);","            pm.expect([201, 409]).to.include(v.res.code);","            if (v.res.code === 409) {","                var e = v.res.json().error;","                pm.expect(e.code).to.eql(\"CONFLICT\");","                pm.expect(e.reason).to.eql(\"IDEMPOTENCY_IN_PROGRESS\");","                pm.expect(v.res.headers.has(\"Retry-After\"),","                    \"sin Retry-After el cliente no sabe cuánto esperar\").to.be.true;","                enCurso += 1;","            } else {","                ids[v.res.json().id] = true;","                if (!v.res.headers.has(\"Idempotent-Replayed\")) { originales += 1; }","            }","        });","        pm.expect(originales, \"dos 201 sin Idempotent-Replayed: la ráfaga creó y cobró DOS reportes\").to.be.at.most(1);","        pm.expect(Object.keys(ids).length, \"dos ids distintos con la MISMA clave\").to.be.at.most(1);","        // El 409 EN CURSO sólo se da por certificado si se VIO: si toda la","        // ráfaga cerró antes, esta afirmación queda en skipped.","        if (!enCurso) {","            console.log(\"La ráfaga no vio ningún 409 en curso: la primera cerró antes que las demás. Volvé a mandar este request.\");","        }","        (enCurso ? pm.test : pm.test.skip)(\"Se observó IDEMPOTENCY_IN_PROGRESS con Retry-After\", function () {","            pm.expect(enCurso).to.be.above(0);","        });","        done();","    }","    for (var i = 0; i < RAFAGA; i++) {","        reenviar(clave, cuerpo, function (err, res) {","            vistas.push({ err: err, res: res });","            cerrar();","        });","    }","});"]}}],"response":[{"name":"3. En curso — misma clave mientras la primera corre → 409 con Retry-After — ejemplo","originalRequest":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"Idempotency-Key","value":"{{cert_key_curso}}","type":"text","description":"Identifica ESTA solicitud. Un reintento por timeout de red con la misma clave devuelve el reporte original —con el header `Idempotent-Replayed: true`— en vez de crear y cobrar otro. Ventana: 24 h. `{{$guid}}` genera una clave nueva en cada envío, que es lo correcto para una solicitud nueva."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/reports/","host":["{{base_url}}"],"path":["api","v1","gateway","api","reports"]},"description":"Después de crear este reporte, el script de test dispara una RÁFAGA: varias creaciones a la vez con una clave NUEVA, todas con la misma. La primera que llega crea; las otras llegan con ésa todavía corriendo. Es la ráfaga real, no una simulación.\n\nCada llamada de la ráfaga tiene dos desenlaces legítimos y los dos se afirman: 409 en curso con `Retry-After` (lo esperable, porque crear un reporte tarda) o el replay —201 con `Idempotent-Replayed: true` y el MISMO `id`— si la primera cerró antes. Lo que NUNCA puede salir son dos 201 sin `Idempotent-Replayed` o dos `id` distintos: eso serían dos reportes y dos cobros.\n\nSi en una corrida todas cerraron antes (no se vio ningún 409), la consola lo avisa: volvé a mandarlo.\n\nQUÉ TIENE QUE PASAR: 409 con `error.reason: IDEMPOTENCY_IN_PROGRESS` y `Retry-After`. Se reintenta con LA MISMA clave. Si la primera alcanzó a terminar, la respuesta es el replay (201 + `Idempotent-Replayed: true`) — nunca un reporte nuevo.\n\nTipos de documento aceptados: CC, CE, NIT, PA.","body":{"mode":"raw","raw":"{\n  \"tipo_documento\": \"CC\",\n  \"numero_documento\": \"900000003\",\n  \"selected_endpoints\": [\n    \"contraloria-natural\"\n  ],\n  \"data_authorization_declared\": true\n}","options":{"raw":{"language":"json"}}}},"status":"Conflict","code":409,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"detail\": \"Hay una solicitud con este Idempotency-Key en curso ahora mismo. Espere unos segundos y reintente con LA MISMA clave.\",\n  \"success\": false,\n  \"error\": {\n    \"code\": \"CONFLICT\",\n    \"message\": \"Hay una solicitud con este Idempotency-Key en curso ahora mismo. Espere unos segundos y reintente con LA MISMA clave.\",\n    \"reason\": \"IDEMPOTENCY_IN_PROGRESS\"\n  },\n  \"retry_after\": 15\n}"}]},{"name":"4. Sin saldo — el 402 LIBERA la clave","request":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"Idempotency-Key","value":"{{cert_key_saldo}}","type":"text","description":"Identifica ESTA solicitud. Un reintento por timeout de red con la misma clave devuelve el reporte original —con el header `Idempotent-Replayed: true`— en vez de crear y cobrar otro. Ventana: 24 h. `{{$guid}}` genera una clave nueva en cada envío, que es lo correcto para una solicitud nueva."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/reports/","host":["{{base_url}}"],"path":["api","v1","gateway","api","reports"]},"description":"Con una key de PRUEBA (`vf_test_`) en `api_key`, el sujeto 900000009 del banco del sandbox responde 402 SIEMPRE, aunque el saldo de prueba esté completo: es el escenario para certificar esto sin vaciar nada.\n\nCon una key live hace falta una organización SIN créditos; si hay saldo, el request responde 201 y las afirmaciones quedan en `skipped` con una nota en la consola — no en rojo, porque no falló nada.\n\nLo que certifica: la clave NO queda tomada por una solicitud que no creó ni cobró nada. Reintentar con ella devuelve otra vez 402 (y 201 en cuanto haya saldo), nunca 409.\n\nQUÉ TIENE QUE PASAR: 402 con `error.code: INSUFFICIENT_CREDITS`, y la MISMA clave vuelve a servir: recargá créditos, mandá la misma clave y responde 201. Un rechazo por saldo no puede dejar el UUID quemado 24 h.\n\nTipos de documento aceptados: CC, CE, NIT, PA.","body":{"mode":"raw","raw":"{\n  \"tipo_documento\": \"CC\",\n  \"numero_documento\": \"900000009\",\n  \"selected_endpoints\": [\n    \"contraloria-natural\"\n  ],\n  \"data_authorization_declared\": true\n}","options":{"raw":{"language":"json"}}}},"id":"cert-sin-saldo","event":[{"listen":"prerequest","script":{"type":"text/javascript","exec":["pm.collectionVariables.set(\"cert_key_saldo\", pm.variables.replaceIn(\"{{$guid}}\"));"]}},{"listen":"test","script":{"type":"text/javascript","exec":["function reenviar(clave, cuerpo, cb) {","    pm.sendRequest({","        url: pm.variables.replaceIn(\"{{base_url}}/api/v1/gateway/api/reports/\"),","        method: \"POST\",","        header: {","            \"X-API-KEY\": pm.variables.replaceIn(\"{{api_key}}\"),","            \"Content-Type\": \"application/json\",","            \"Idempotency-Key\": clave","        },","        body: { mode: \"raw\", raw: cuerpo }","    }, cb);","}","","var sinSaldo = pm.response.code === 402;","var esKeyDePrueba = (pm.variables.replaceIn(\"{{api_key}}\") || \"\").indexOf(\"vf_test_\") === 0;","","pm.test(\"402, o 201 si la organización tiene saldo (con una key de prueba, sólo 402)\", function () {","    pm.expect(esKeyDePrueba ? [402] : [402, 201]).to.include(pm.response.code);","});","","(sinSaldo ? pm.test : pm.test.skip)(\"El 402 declara INSUFFICIENT_CREDITS\", function () {","    pm.expect(pm.response.json().error.code).to.eql(\"INSUFFICIENT_CREDITS\");","});","","(sinSaldo ? pm.test : pm.test.skip)(\"El 402 libera la clave: reintentarla NO da 409\", function (done) {","    reenviar(pm.collectionVariables.get(\"cert_key_saldo\"), pm.request.body.raw, function (err, res) {","        pm.expect(err).to.equal(null);","        pm.expect(res.code,","            \"la clave quedó tomada por un cobro que nunca ocurrió\").to.not.eql(409);","        if (esKeyDePrueba) {","            pm.expect(res.code, \"el sujeto del banco vuelve a dar 402 con la MISMA clave\").to.eql(402);","        }","        done();","    });","});","","if (!sinSaldo) {","    console.log(\"Este caso necesita una key de prueba (vf_test_) o una organización SIN créditos (402). Respondió \" +","        pm.response.code + \".\");","}"]}}],"response":[{"name":"4. Sin saldo — el 402 LIBERA la clave — ejemplo","originalRequest":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"Idempotency-Key","value":"{{cert_key_saldo}}","type":"text","description":"Identifica ESTA solicitud. Un reintento por timeout de red con la misma clave devuelve el reporte original —con el header `Idempotent-Replayed: true`— en vez de crear y cobrar otro. Ventana: 24 h. `{{$guid}}` genera una clave nueva en cada envío, que es lo correcto para una solicitud nueva."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/reports/","host":["{{base_url}}"],"path":["api","v1","gateway","api","reports"]},"description":"Con una key de PRUEBA (`vf_test_`) en `api_key`, el sujeto 900000009 del banco del sandbox responde 402 SIEMPRE, aunque el saldo de prueba esté completo: es el escenario para certificar esto sin vaciar nada.\n\nCon una key live hace falta una organización SIN créditos; si hay saldo, el request responde 201 y las afirmaciones quedan en `skipped` con una nota en la consola — no en rojo, porque no falló nada.\n\nLo que certifica: la clave NO queda tomada por una solicitud que no creó ni cobró nada. Reintentar con ella devuelve otra vez 402 (y 201 en cuanto haya saldo), nunca 409.\n\nQUÉ TIENE QUE PASAR: 402 con `error.code: INSUFFICIENT_CREDITS`, y la MISMA clave vuelve a servir: recargá créditos, mandá la misma clave y responde 201. Un rechazo por saldo no puede dejar el UUID quemado 24 h.\n\nTipos de documento aceptados: CC, CE, NIT, PA.","body":{"mode":"raw","raw":"{\n  \"tipo_documento\": \"CC\",\n  \"numero_documento\": \"900000009\",\n  \"selected_endpoints\": [\n    \"contraloria-natural\"\n  ],\n  \"data_authorization_declared\": true\n}","options":{"raw":{"language":"json"}}}},"status":"Payment Required","code":402,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"detail\": \"Créditos insuficientes para ejecutar la verificación.\",\n  \"success\": false,\n  \"error\": {\n    \"code\": \"INSUFFICIENT_CREDITS\",\n    \"message\": \"Créditos insuficientes para ejecutar la verificación.\"\n  }\n}"}]},{"name":"5. Consentimiento del titular — el 202 también es idempotente","request":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"Idempotency-Key","value":"{{cert_key_consent}}","type":"text","description":"Identifica ESTA solicitud. Un reintento por timeout de red con la misma clave devuelve el reporte original —con el header `Idempotent-Replayed: true`— en vez de crear y cobrar otro. Ventana: 24 h. `{{$guid}}` genera una clave nueva en cada envío, que es lo correcto para una solicitud nueva."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/reports/","host":["{{base_url}}"],"path":["api","v1","gateway","api","reports"]},"description":"Con una key de PRUEBA (`vf_test_`) en `api_key`, el sujeto 900000006 del banco del sandbox exige la autorización del titular y responde 202 aunque tu organización no la exija, SIN mandar ningún correo.\n\nCon una key live necesita una organización con el consentimiento del titular exigido. Si no lo exige, la creación responde 201 y las afirmaciones quedan en `skipped`.\n\nEs el caso que más fácil se rompe al implementar idempotencia: la clave apunta a un CONSENT y no a un reporte, y un replay que intente releerlo como reporte termina creando —y cobrando— un reporte que el integrador nunca pidió.\n\nQUÉ TIENE QUE PASAR: 202 con `consent_id` y `consent_status`; el reintento con la misma clave devuelve el MISMO `consent_id` con `Idempotent-Replayed: true` y NO manda un segundo correo al titular.\n\nTipos de documento aceptados: CC, CE, NIT, PA.","body":{"mode":"raw","raw":"{\n  \"tipo_documento\": \"CC\",\n  \"numero_documento\": \"900000006\",\n  \"selected_endpoints\": [\n    \"contraloria-natural\"\n  ],\n  \"data_authorization_declared\": true,\n  \"titular_email\": \"titular.de.prueba@example.com\"\n}","options":{"raw":{"language":"json"}}}},"id":"cert-consentimiento","event":[{"listen":"prerequest","script":{"type":"text/javascript","exec":["pm.collectionVariables.set(\"cert_key_consent\", pm.variables.replaceIn(\"{{$guid}}\"));"]}},{"listen":"test","script":{"type":"text/javascript","exec":["function reenviar(clave, cuerpo, cb) {","    pm.sendRequest({","        url: pm.variables.replaceIn(\"{{base_url}}/api/v1/gateway/api/reports/\"),","        method: \"POST\",","        header: {","            \"X-API-KEY\": pm.variables.replaceIn(\"{{api_key}}\"),","            \"Content-Type\": \"application/json\",","            \"Idempotency-Key\": clave","        },","        body: { mode: \"raw\", raw: cuerpo }","    }, cb);","}","","var espera202 = pm.response.code === 202;","var esKeyDePrueba = (pm.variables.replaceIn(\"{{api_key}}\") || \"\").indexOf(\"vf_test_\") === 0;","","pm.test(\"202, o 201 si la organización no exige el titular (con una key de prueba, sólo 202)\", function () {","    pm.expect(esKeyDePrueba ? [202] : [202, 201]).to.include(pm.response.code);","});","","(espera202 ? pm.test : pm.test.skip)(\"El 202 trae consent_id y consent_status\", function () {","    var b = pm.response.json();","    pm.expect(b.status).to.eql(\"pending_titular_consent\");","    pm.expect(b.consent_id).to.be.a(\"string\");","    pm.expect(b.consent_status, \"sin consent_status hay que ir a buscar el estado a otra llamada\").to.be.a(\"string\");","});","","(espera202 ? pm.test : pm.test.skip)(\"El reintento devuelve el MISMO consent_id y no manda un segundo correo\", function (done) {","    var consent = pm.response.json().consent_id;","    reenviar(pm.collectionVariables.get(\"cert_key_consent\"), pm.request.body.raw, function (err, res) {","        pm.expect(err).to.equal(null);","        pm.expect(res.code).to.eql(202);","        pm.expect(res.json().consent_id,","            \"otro consent_id: al titular le llegó un segundo correo\").to.eql(consent);","        pm.expect(res.headers.has(\"Idempotent-Replayed\")).to.be.true;","        done();","    });","});","","if (!espera202) {","    console.log(\"Este caso necesita una organización que exija el consentimiento del titular (202). Respondió \" + pm.response.code + \".\");","}"]}}],"response":[{"name":"5. Consentimiento del titular — el 202 también es idempotente — ejemplo","originalRequest":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"Idempotency-Key","value":"{{cert_key_consent}}","type":"text","description":"Identifica ESTA solicitud. Un reintento por timeout de red con la misma clave devuelve el reporte original —con el header `Idempotent-Replayed: true`— en vez de crear y cobrar otro. Ventana: 24 h. `{{$guid}}` genera una clave nueva en cada envío, que es lo correcto para una solicitud nueva."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/reports/","host":["{{base_url}}"],"path":["api","v1","gateway","api","reports"]},"description":"Con una key de PRUEBA (`vf_test_`) en `api_key`, el sujeto 900000006 del banco del sandbox exige la autorización del titular y responde 202 aunque tu organización no la exija, SIN mandar ningún correo.\n\nCon una key live necesita una organización con el consentimiento del titular exigido. Si no lo exige, la creación responde 201 y las afirmaciones quedan en `skipped`.\n\nEs el caso que más fácil se rompe al implementar idempotencia: la clave apunta a un CONSENT y no a un reporte, y un replay que intente releerlo como reporte termina creando —y cobrando— un reporte que el integrador nunca pidió.\n\nQUÉ TIENE QUE PASAR: 202 con `consent_id` y `consent_status`; el reintento con la misma clave devuelve el MISMO `consent_id` con `Idempotent-Replayed: true` y NO manda un segundo correo al titular.\n\nTipos de documento aceptados: CC, CE, NIT, PA.","body":{"mode":"raw","raw":"{\n  \"tipo_documento\": \"CC\",\n  \"numero_documento\": \"900000006\",\n  \"selected_endpoints\": [\n    \"contraloria-natural\"\n  ],\n  \"data_authorization_declared\": true,\n  \"titular_email\": \"titular.de.prueba@example.com\"\n}","options":{"raw":{"language":"json"}}}},"status":"Accepted","code":202,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"pending_titular_consent\",\n  \"consent_id\": \"b41d7c92-8e5a-4f10-9c33-70a2d6e8b155\",\n  \"consent_status\": \"pending\",\n  \"message\": \"Se envió una solicitud de autorización al titular por correo. La verificación se ejecutará cuando el titular acepte.\"\n}"}]},{"name":"6. Ventana de 24 h — pasada la ventana, la clave crea un reporte nuevo","request":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"Idempotency-Key","value":"{{cert_key_24h}}","type":"text","description":"Identifica ESTA solicitud. Un reintento por timeout de red con la misma clave devuelve el reporte original —con el header `Idempotent-Replayed: true`— en vez de crear y cobrar otro. Ventana: 24 h. `{{$guid}}` genera una clave nueva en cada envío, que es lo correcto para una solicitud nueva."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/reports/","host":["{{base_url}}"],"path":["api","v1","gateway","api","reports"]},"description":"El único caso que no se certifica en una corrida: hay que mandarlo DOS veces, con más de 24 horas entre una y otra.\n\n· 1ª corrida — guarda la clave y el `id` en las variables de la colección.\n· Antes de las 24 h — afirma que la clave sigue devolviendo el MISMO reporte (la mitad de la promesa que se olvida certificar).\n· Después de las 24 h — afirma que crea uno NUEVO.\n\nPara reiniciar el caso, borrá las variables `cert_key_24h`, `cert_report_24h` y `cert_ts_24h`.\n\nQUÉ TIENE QUE PASAR: Dentro de las 24 h, la misma clave devuelve el mismo reporte. Pasadas las 24 h, la clave se libera: `id` NUEVO, sin `Idempotent-Replayed`, y se cobra otra vez.\n\nTipos de documento aceptados: CC, CE, NIT, PA.","body":{"mode":"raw","raw":"{\n  \"tipo_documento\": \"CC\",\n  \"numero_documento\": \"900000003\",\n  \"selected_endpoints\": [\n    \"contraloria-natural\"\n  ],\n  \"data_authorization_declared\": true\n}","options":{"raw":{"language":"json"}}}},"id":"cert-clave-vencida","event":[{"listen":"prerequest","script":{"type":"text/javascript","exec":["// La MISMA clave entre corridas: es lo que se está midiendo.","if (!pm.collectionVariables.get(\"cert_key_24h\")) {","    pm.collectionVariables.set(\"cert_key_24h\", pm.variables.replaceIn(\"{{$guid}}\"));","}"]}},{"listen":"test","script":{"type":"text/javascript","exec":["var previo = pm.collectionVariables.get(\"cert_report_24h\");","var desde = Number(pm.collectionVariables.get(\"cert_ts_24h\") || 0);","var horas = (Date.now() - desde) / 3600000;","","pm.test(\"La creación responde 201\", function () {","    pm.response.to.have.status(201);","});","","if (pm.response.code !== 201) {","    // Sin 201 no hay nada que guardar ni comparar: el test de arriba ya está en rojo.","} else if (!previo) {","    pm.collectionVariables.set(\"cert_report_24h\", pm.response.json().id);","    pm.collectionVariables.set(\"cert_ts_24h\", String(Date.now()));","    console.log(\"1ª corrida guardada. Volvé a mandar ESTE request pasadas más de 24 h: la clave habrá vencido y tiene que crear un reporte NUEVO.\");","} else if (horas < 24) {","    pm.test(\"Dentro de la ventana, la MISMA clave devuelve el MISMO reporte\", function () {","        pm.expect(pm.response.json().id).to.eql(previo);","        pm.expect(pm.response.headers.has(\"Idempotent-Replayed\")).to.be.true;","    });","} else {","    pm.test(\"Pasadas 24 h la clave se libera: id NUEVO y sin Idempotent-Replayed\", function () {","        pm.expect(pm.response.json().id,","            \"la clave vencida devolvió el reporte viejo: la ventana no expira\").to.not.eql(previo);","        pm.expect(pm.response.headers.has(\"Idempotent-Replayed\")).to.be.false;","    });","    // El reporte nuevo pasa a ser la referencia de la próxima corrida.","    pm.collectionVariables.set(\"cert_report_24h\", pm.response.json().id);","    pm.collectionVariables.set(\"cert_ts_24h\", String(Date.now()));","}"]}}],"response":[{"name":"6. Ventana de 24 h — pasada la ventana, la clave crea un reporte nuevo — ejemplo","originalRequest":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"Idempotency-Key","value":"{{cert_key_24h}}","type":"text","description":"Identifica ESTA solicitud. Un reintento por timeout de red con la misma clave devuelve el reporte original —con el header `Idempotent-Replayed: true`— en vez de crear y cobrar otro. Ventana: 24 h. `{{$guid}}` genera una clave nueva en cada envío, que es lo correcto para una solicitud nueva."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/reports/","host":["{{base_url}}"],"path":["api","v1","gateway","api","reports"]},"description":"El único caso que no se certifica en una corrida: hay que mandarlo DOS veces, con más de 24 horas entre una y otra.\n\n· 1ª corrida — guarda la clave y el `id` en las variables de la colección.\n· Antes de las 24 h — afirma que la clave sigue devolviendo el MISMO reporte (la mitad de la promesa que se olvida certificar).\n· Después de las 24 h — afirma que crea uno NUEVO.\n\nPara reiniciar el caso, borrá las variables `cert_key_24h`, `cert_report_24h` y `cert_ts_24h`.\n\nQUÉ TIENE QUE PASAR: Dentro de las 24 h, la misma clave devuelve el mismo reporte. Pasadas las 24 h, la clave se libera: `id` NUEVO, sin `Idempotent-Replayed`, y se cobra otra vez.\n\nTipos de documento aceptados: CC, CE, NIT, PA.","body":{"mode":"raw","raw":"{\n  \"tipo_documento\": \"CC\",\n  \"numero_documento\": \"900000003\",\n  \"selected_endpoints\": [\n    \"contraloria-natural\"\n  ],\n  \"data_authorization_declared\": true\n}","options":{"raw":{"language":"json"}}}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": \"3f2a8c10-5b7e-4d21-9a44-1c8e6b0d5f93\",\n  \"status\": \"processing\",\n  \"overall_status\": null,\n  \"subject_document_type\": \"CC\",\n  \"subject_document_number\": \"900000003\",\n  \"subject_full_name\": null,\n  \"total_sources\": 1,\n  \"completed_sources\": 0,\n  \"successful_sources\": 0,\n  \"failed_sources\": 0,\n  \"sources\": [],\n  \"total_credits_charged\": 1,\n  \"credits_reserved\": 1,\n  \"credits_refunded\": 0,\n  \"omitted_sources\": [],\n  \"omitted_sources_count\": 0,\n  \"has_pdf\": false,\n  \"pdf_generated_at\": null,\n  \"created_at\": \"2026-09-02T14:05:11Z\",\n  \"completed_at\": null,\n  \"deduplicated\": false,\n  \"origin\": null,\n  \"environment\": \"live\",\n  \"test_mode\": false,\n  \"external_reference\": null,\n  \"correlation_id\": null,\n  \"informational_only\": false,\n  \"informational_sources\": 0,\n  \"conclusive_sources\": 0,\n  \"coverage_sufficient\": false,\n  \"covered_dimensions\": [],\n  \"uncovered_dimensions\": [],\n  \"uncovered_coverage_groups\": [],\n  \"narrative_status\": \"none\",\n  \"risk_analysis\": null,\n  \"risk_narrative\": null,\n  \"narrative_generated_at\": null\n}"}]}],"description":"Los seis casos que hacen falta para CERTIFICAR que un reintento no crea ni cobra dos veces. Cada request trae sus `pm.test` y hace su propia segunda llamada, así que se corren de a uno o de un tirón con el Collection Runner.\n\nAntes de correr: pegá tu API key en la variable `api_key`. Cada envío consulta UNA fuente (1 crédito), no el reporte completo: la ronda entera sale por menos de diez créditos.\n\nCON UNA KEY DE PRUEBA (`vf_test_`) en `api_key` los seis casos corren en el sandbox, gratis, y los casos 4 y 5 se certifican sin preparar nada: usan los sujetos del banco 900000009 (402 forzado) y 900000006 (202 del titular, sin correo).\n\nCon una key live, esos dos casos necesitan una organización preparada y, si no lo está, dejan sus afirmaciones en `skipped` con una nota en la consola en vez de en rojo: el 4 pide una organización SIN saldo y el 5 una que exija el consentimiento del titular. El caso 6 se corre dos veces, con más de 24 horas entre medio."},{"name":"5 · Consentimiento del titular (el 202)","item":[{"name":"Crear reporte que devuelve 202","request":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"Idempotency-Key","value":"{{idempotency_key}}","type":"text","description":"Identifica ESTA solicitud. Un reintento por timeout de red con la misma clave devuelve el reporte original —con el header `Idempotent-Replayed: true`— en vez de crear y cobrar otro. Ventana: 24 h. `{{$guid}}` genera una clave nueva en cada envío, que es lo correcto para una solicitud nueva."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/reports/","host":["{{base_url}}"],"path":["api","v1","gateway","api","reports"]},"description":"Cuando tu organización exige el consentimiento del titular, la creación responde **202** y NO crea reporte ni cobra nada: se le manda un correo al titular y la verificación corre sola cuando acepta.\n\n`titular_email` es OBLIGATORIO en ese caso: sin él, 422.\n\nCon una key de PRUEBA (`vf_test_`) en `api_key`, el sujeto 900000006 del banco del sandbox responde este 202 aunque tu organización no exija el consentimiento, y NO manda ningún correo: el 202 trae `sandbox.accept_endpoint` para simular la autorización.\n\nEste 202 **también es idempotente**: reintentar con la misma `Idempotency-Key` devuelve el MISMO `consent_id` con `Idempotent-Replayed: true`, y al titular NO le llega un segundo correo.\n\n⚠ Con una key live (`vf_live_`), si tu organización NO exige el consentimiento del titular, este request crea y cobra UNA fuente (`contraloria-natural`) sobre el documento sintético.\n\nEl script guarda `consent_id` en las variables de la colección para el request de abajo.\n\nTipos de documento aceptados: CC, CE, NIT, PA. OJO: el reporte acepta MENOS tipos que la consulta directa por fuente —que admite hasta CC, CE, NIT, PA, PPT y TI según la fuente—. Un tipo fuera de este conjunto NO omite una fuente: rechaza el reporte entero.","body":{"mode":"raw","raw":"{\n  \"tipo_documento\": \"CC\",\n  \"numero_documento\": \"900000006\",\n  \"data_authorization_declared\": true,\n  \"selected_endpoints\": [\n    \"contraloria-natural\"\n  ],\n  \"titular_email\": \"titular.de.prueba@example.com\"\n}","options":{"raw":{"language":"json"}}}},"id":"consent-202","event":[{"listen":"prerequest","script":{"type":"text/javascript","exec":["// Una clave nueva por solicitud. Para probar el replay del 202,","// fijá `idempotency_key` a mano y volvé a mandar este request.","if (!pm.collectionVariables.get(\"idempotency_key\")) {","    pm.collectionVariables.set(\"idempotency_key\", pm.variables.replaceIn(\"{{$guid}}\"));","}"]}},{"listen":"test","script":{"type":"text/javascript","exec":["var es202 = pm.response.code === 202;","// El consent de la corrida ANTERIOR, leído ANTES de pisarlo: si se","// leyera después, el chequeo del replay se compararía consigo","// mismo y pasaría en verde siempre.","var previo = pm.collectionVariables.get(\"consent_id\");","","(es202 ? pm.test : pm.test.skip)(\"El 202 trae consent_id y consent_status\", function () {","    var b = pm.response.json();","    pm.expect(b.status).to.eql(\"pending_titular_consent\");","    pm.expect(b.consent_id, \"sin consent_id el 202 no se puede cerrar\").to.be.a(\"string\");","    pm.expect(b.consent_status,","        \"sin consent_status hay que ir a buscar el estado a otra llamada\").to.be.oneOf(","        [\"pending\", \"granted\", \"rejected\", \"expired\"]);","    pm.collectionVariables.set(\"consent_id\", b.consent_id);","});","","pm.test(\"201 o 202, nunca otra cosa: hay que programar los DOS\", function () {","    pm.expect([201, 202]).to.include(pm.response.code);","});","","// Mandá este request DOS veces con la misma `idempotency_key`: la","// segunda tiene que traer `Idempotent-Replayed: true` y el MISMO","// `consent_id`. Un consent_id nuevo significa que al titular le","// llegó un segundo correo.","if (pm.response.headers.has(\"Idempotent-Replayed\")) {","    pm.test(\"El replay del 202 devuelve el MISMO consent_id y no manda otro correo\", function () {","        pm.expect(pm.response.json().consent_id,","            \"otro consent_id: al titular le llegó un segundo correo\").to.eql(previo);","    });","}","","if (!es202) {","    console.log(\"Tu organización no exige el consentimiento del titular: respondió \" +","        pm.response.code + \". El reporte se creó normalmente.\");","}"]}}],"response":[{"name":"Crear reporte que devuelve 202 — ejemplo","originalRequest":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"Idempotency-Key","value":"{{idempotency_key}}","type":"text","description":"Identifica ESTA solicitud. Un reintento por timeout de red con la misma clave devuelve el reporte original —con el header `Idempotent-Replayed: true`— en vez de crear y cobrar otro. Ventana: 24 h. `{{$guid}}` genera una clave nueva en cada envío, que es lo correcto para una solicitud nueva."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/reports/","host":["{{base_url}}"],"path":["api","v1","gateway","api","reports"]},"description":"Cuando tu organización exige el consentimiento del titular, la creación responde **202** y NO crea reporte ni cobra nada: se le manda un correo al titular y la verificación corre sola cuando acepta.\n\n`titular_email` es OBLIGATORIO en ese caso: sin él, 422.\n\nCon una key de PRUEBA (`vf_test_`) en `api_key`, el sujeto 900000006 del banco del sandbox responde este 202 aunque tu organización no exija el consentimiento, y NO manda ningún correo: el 202 trae `sandbox.accept_endpoint` para simular la autorización.\n\nEste 202 **también es idempotente**: reintentar con la misma `Idempotency-Key` devuelve el MISMO `consent_id` con `Idempotent-Replayed: true`, y al titular NO le llega un segundo correo.\n\n⚠ Con una key live (`vf_live_`), si tu organización NO exige el consentimiento del titular, este request crea y cobra UNA fuente (`contraloria-natural`) sobre el documento sintético.\n\nEl script guarda `consent_id` en las variables de la colección para el request de abajo.\n\nTipos de documento aceptados: CC, CE, NIT, PA. OJO: el reporte acepta MENOS tipos que la consulta directa por fuente —que admite hasta CC, CE, NIT, PA, PPT y TI según la fuente—. Un tipo fuera de este conjunto NO omite una fuente: rechaza el reporte entero.","body":{"mode":"raw","raw":"{\n  \"tipo_documento\": \"CC\",\n  \"numero_documento\": \"900000006\",\n  \"data_authorization_declared\": true,\n  \"selected_endpoints\": [\n    \"contraloria-natural\"\n  ],\n  \"titular_email\": \"titular.de.prueba@example.com\"\n}","options":{"raw":{"language":"json"}}}},"status":"Accepted","code":202,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"pending_titular_consent\",\n  \"consent_id\": \"b41d7c92-8e5a-4f10-9c33-70a2d6e8b155\",\n  \"consent_status\": \"pending\",\n  \"message\": \"Se envió una solicitud de autorización al titular por correo. La verificación se ejecutará cuando el titular acepte.\"\n}"},{"name":"Crear reporte que devuelve 202 (replay) — ejemplo","originalRequest":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"Idempotency-Key","value":"{{idempotency_key}}","type":"text","description":"Identifica ESTA solicitud. Un reintento por timeout de red con la misma clave devuelve el reporte original —con el header `Idempotent-Replayed: true`— en vez de crear y cobrar otro. Ventana: 24 h. `{{$guid}}` genera una clave nueva en cada envío, que es lo correcto para una solicitud nueva."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/reports/","host":["{{base_url}}"],"path":["api","v1","gateway","api","reports"]},"description":"Cuando tu organización exige el consentimiento del titular, la creación responde **202** y NO crea reporte ni cobra nada: se le manda un correo al titular y la verificación corre sola cuando acepta.\n\n`titular_email` es OBLIGATORIO en ese caso: sin él, 422.\n\nCon una key de PRUEBA (`vf_test_`) en `api_key`, el sujeto 900000006 del banco del sandbox responde este 202 aunque tu organización no exija el consentimiento, y NO manda ningún correo: el 202 trae `sandbox.accept_endpoint` para simular la autorización.\n\nEste 202 **también es idempotente**: reintentar con la misma `Idempotency-Key` devuelve el MISMO `consent_id` con `Idempotent-Replayed: true`, y al titular NO le llega un segundo correo.\n\n⚠ Con una key live (`vf_live_`), si tu organización NO exige el consentimiento del titular, este request crea y cobra UNA fuente (`contraloria-natural`) sobre el documento sintético.\n\nEl script guarda `consent_id` en las variables de la colección para el request de abajo.\n\nTipos de documento aceptados: CC, CE, NIT, PA. OJO: el reporte acepta MENOS tipos que la consulta directa por fuente —que admite hasta CC, CE, NIT, PA, PPT y TI según la fuente—. Un tipo fuera de este conjunto NO omite una fuente: rechaza el reporte entero.","body":{"mode":"raw","raw":"{\n  \"tipo_documento\": \"CC\",\n  \"numero_documento\": \"900000006\",\n  \"data_authorization_declared\": true,\n  \"selected_endpoints\": [\n    \"contraloria-natural\"\n  ],\n  \"titular_email\": \"titular.de.prueba@example.com\"\n}","options":{"raw":{"language":"json"}}}},"status":"Accepted","code":202,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"},{"key":"Idempotent-Replayed","value":"true"}],"body":"{\n  \"status\": \"pending_titular_consent\",\n  \"consent_id\": \"b41d7c92-8e5a-4f10-9c33-70a2d6e8b155\",\n  \"consent_status\": \"pending\",\n  \"message\": \"Se envió una solicitud de autorización al titular por correo. La verificación se ejecutará cuando el titular acepte.\"\n}"}]},{"name":"Consultar el consentimiento","request":{"method":"GET","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/consents/{{consent_id}}","host":["{{base_url}}"],"path":["api","v1","gateway","api","consents","{{consent_id}}"]},"description":"Cierra el flujo 202. Sondealo hasta que `status` deje de ser `pending`.\n\n· `pending` — el titular todavía no respondió. `report_id` es **null**.\n· `granted` — autorizó, la verificación ya corrió y `report_id` trae el id del reporte. Es el ÚNICO lugar donde lo vas a descubrir: ese reporte nació mucho después de tu 202.\n· `rejected` / `expired` — no autorizó, o venció el enlace de 7 días. No hay reporte y no se cobró nada.\n\nCon el `report_id` seguís por `GET /api/v1/gateway/api/reports/{id}` como con cualquier otro reporte."},"id":"consent-get","event":[{"listen":"prerequest","script":{"type":"text/javascript","exec":["if (!pm.variables.get(\"consent_id\")) {","    console.warn(\"Falta la variable `consent_id`: este request no se mandó.\");","    pm.execution.skipRequest();","}"]}},{"listen":"test","script":{"type":"text/javascript","exec":["pm.test(\"El estado usa el vocabulario del canal\", function () {","    pm.response.to.have.status(200);","    var b = pm.response.json();","    pm.expect(b.status).to.be.oneOf([\"pending\", \"granted\", \"rejected\", \"expired\"]);","});","","pm.test(\"Con granted llega el report_id, y con pending no puede llegar\", function () {","    var b = pm.response.json();","    if (b.status === \"granted\") {","        pm.expect(b.report_id, \"granted sin report_id: el reporte es inalcanzable\").to.be.a(\"string\");","        pm.collectionVariables.set(\"report_id\", b.report_id);","    } else {","        pm.expect(b.report_id,","            \"report_id antes de que el titular acepte: se cobró sin autorización\").to.be.null;","    }","});","","pm.test(\"El documento del titular llega enmascarado y sin datos internos (C2)\", function () {","    var b = pm.response.json();","    if (b.subject_document_number) {","        pm.expect(b.subject_document_number, \"sólo se ven los últimos 4\").to.match(/^•+.{0,4}$/);","    }","    pm.expect(b).to.not.have.property(\"user_id\");","    pm.expect(b).to.not.have.property(\"organization_id\");","});"]}}],"response":[{"name":"Consultar el consentimiento — ejemplo","originalRequest":{"method":"GET","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/consents/{{consent_id}}","host":["{{base_url}}"],"path":["api","v1","gateway","api","consents","{{consent_id}}"]},"description":"Cierra el flujo 202. Sondealo hasta que `status` deje de ser `pending`.\n\n· `pending` — el titular todavía no respondió. `report_id` es **null**.\n· `granted` — autorizó, la verificación ya corrió y `report_id` trae el id del reporte. Es el ÚNICO lugar donde lo vas a descubrir: ese reporte nació mucho después de tu 202.\n· `rejected` / `expired` — no autorizó, o venció el enlace de 7 días. No hay reporte y no se cobró nada.\n\nCon el `report_id` seguís por `GET /api/v1/gateway/api/reports/{id}` como con cualquier otro reporte."},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": \"b41d7c92-8e5a-4f10-9c33-70a2d6e8b155\",\n  \"verification_kind\": \"report\",\n  \"method\": \"titular_email\",\n  \"status\": \"pending\",\n  \"subject_document_type\": \"CC\",\n  \"subject_document_number\": \"•••••0006\",\n  \"subjects_count\": 1,\n  \"tyc_version\": \"2026-06-01\",\n  \"report_id\": null,\n  \"batch_id\": null,\n  \"task_id\": null,\n  \"ip_address\": null,\n  \"user_agent\": null,\n  \"accepted_at\": null,\n  \"environment\": \"live\",\n  \"created_at\": \"2026-09-02T14:05:11Z\"\n}"},{"name":"Consultar el consentimiento (granted) — ejemplo","originalRequest":{"method":"GET","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/consents/{{consent_id}}","host":["{{base_url}}"],"path":["api","v1","gateway","api","consents","{{consent_id}}"]},"description":"Cierra el flujo 202. Sondealo hasta que `status` deje de ser `pending`.\n\n· `pending` — el titular todavía no respondió. `report_id` es **null**.\n· `granted` — autorizó, la verificación ya corrió y `report_id` trae el id del reporte. Es el ÚNICO lugar donde lo vas a descubrir: ese reporte nació mucho después de tu 202.\n· `rejected` / `expired` — no autorizó, o venció el enlace de 7 días. No hay reporte y no se cobró nada.\n\nCon el `report_id` seguís por `GET /api/v1/gateway/api/reports/{id}` como con cualquier otro reporte."},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": \"b41d7c92-8e5a-4f10-9c33-70a2d6e8b155\",\n  \"verification_kind\": \"report\",\n  \"method\": \"titular_email\",\n  \"status\": \"granted\",\n  \"subject_document_type\": \"CC\",\n  \"subject_document_number\": \"•••••0006\",\n  \"subjects_count\": 1,\n  \"tyc_version\": \"2026-06-01\",\n  \"report_id\": \"3f2a8c10-5b7e-4d21-9a44-1c8e6b0d5f93\",\n  \"batch_id\": null,\n  \"task_id\": null,\n  \"ip_address\": null,\n  \"user_agent\": null,\n  \"accepted_at\": \"2026-09-02T14:07:36Z\",\n  \"environment\": \"live\",\n  \"created_at\": \"2026-09-02T14:05:11Z\"\n}"}]}],"description":"Qué hacer cuando la creación responde 202 en vez de 201. Es el camino que más fácil se programa mal: un cliente que asume 201 se rompe, y uno que recibe el `consent_id` y no tiene dónde consultarlo se queda esperando para siempre un reporte que todavía no existe."},{"name":"6 · Créditos y conciliación","item":[{"name":"Saldo de créditos","request":{"method":"GET","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/credits/balance","host":["{{base_url}}"],"path":["api","v1","gateway","api","credits","balance"]},"description":"El saldo de la organización de la key, el consumo del mes en curso y la fecha del último movimiento. Es el mismo número que `available_credits` del estimate, sin tener que cotizar nada.\n\nOJO con el tipo: los créditos viajan como STRING (`\"4973\"`), no como número."},"response":[{"name":"Saldo de créditos — ejemplo","originalRequest":{"method":"GET","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/credits/balance","host":["{{base_url}}"],"path":["api","v1","gateway","api","credits","balance"]},"description":"El saldo de la organización de la key, el consumo del mes en curso y la fecha del último movimiento. Es el mismo número que `available_credits` del estimate, sin tener que cotizar nada.\n\nOJO con el tipo: los créditos viajan como STRING (`\"4973\"`), no como número."},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"organization_id\": \"7c1e4a90-2b33-4c58-9f0d-5ab7e2c41d68\",\n  \"available_credits\": \"4973\",\n  \"used_this_month\": \"27\",\n  \"last_transaction_at\": \"2026-09-02T14:07:36Z\",\n  \"next_reset_at\": \"2026-10-01T00:00:00Z\"\n}"}],"event":[{"listen":"test","script":{"type":"text/javascript","exec":["pm.test(\"El saldo llega con su organización\", function () {","    pm.response.to.have.status(200);","    var b = pm.response.json();","    pm.expect(b.organization_id).to.be.a(\"string\");","    pm.expect(Number(b.available_credits)).to.be.at.least(0);","});"]}}]},{"name":"Movimientos (libro de créditos)","request":{"method":"GET","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/credits/transactions?limit=50","host":["{{base_url}}"],"path":["api","v1","gateway","api","credits","transactions"],"query":[{"key":"limit","value":"50"}]},"description":"El historial de la organización, del más reciente al más viejo.\n\nTipos: `purchase`, `consumption`, `adjustment`, `bonus`, `refund`. `consumption` RESTA y el resto suma: el signo lo da `transaction_type`; `amount` llega positivo. `balance_before` y `balance_after` vienen en cada movimiento, así que la suma se audita sin reconstruirla.\n\nFiltros: `transaction_type`, `reference`, `start_date`, `end_date`, `skip`, `limit`. Un `transaction_type` que no esté en la lista se rechaza con 422 en vez de devolver la lista vacía sin decir por qué."},"response":[{"name":"Movimientos (libro de créditos) — ejemplo","originalRequest":{"method":"GET","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/credits/transactions?limit=50","host":["{{base_url}}"],"path":["api","v1","gateway","api","credits","transactions"],"query":[{"key":"limit","value":"50"}]},"description":"El historial de la organización, del más reciente al más viejo.\n\nTipos: `purchase`, `consumption`, `adjustment`, `bonus`, `refund`. `consumption` RESTA y el resto suma: el signo lo da `transaction_type`; `amount` llega positivo. `balance_before` y `balance_after` vienen en cada movimiento, así que la suma se audita sin reconstruirla.\n\nFiltros: `transaction_type`, `reference`, `start_date`, `end_date`, `skip`, `limit`. Un `transaction_type` que no esté en la lista se rechaza con 422 en vez de devolver la lista vacía sin decir por qué."},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"[\n  {\n    \"id\": \"9a1b2c3d-4e5f-6071-8293-a4b5c6d7e8f9\",\n    \"transaction_type\": \"refund\",\n    \"amount\": 1,\n    \"balance_before\": 4972,\n    \"balance_after\": 4973,\n    \"description\": \"Devolución por fuente fallida (dian-rut-estado)\",\n    \"reference\": \"3f2a8c10-5b7e-4d21-9a44-1c8e6b0d5f93\",\n    \"reference_type\": \"report_refund\",\n    \"metadata\": {\n      \"endpoints\": [\n        \"dian-rut-estado\"\n      ]\n    },\n    \"correlation_id\": \"mi-traza-9f3c\",\n    \"created_at\": \"2026-09-02T14:07:36Z\"\n  },\n  {\n    \"id\": \"1f2e3d4c-5b6a-7988-9a0b-1c2d3e4f5a6b\",\n    \"transaction_type\": \"consumption\",\n    \"amount\": 14,\n    \"balance_before\": 4986,\n    \"balance_after\": 4972,\n    \"description\": \"Reserva del reporte de verificación\",\n    \"reference\": \"3f2a8c10-5b7e-4d21-9a44-1c8e6b0d5f93\",\n    \"reference_type\": \"report_reservation\",\n    \"metadata\": {\n      \"sources\": 14\n    },\n    \"correlation_id\": \"mi-traza-9f3c\",\n    \"created_at\": \"2026-09-02T14:05:11Z\"\n  }\n]"}],"event":[{"listen":"test","script":{"type":"text/javascript","exec":["pm.test(\"El libro es una lista de movimientos con saldo antes y después\", function () {","    pm.response.to.have.status(200);","    var b = pm.response.json();","    pm.expect(b).to.be.an(\"array\");","    if (b.length) {","        pm.expect(b[0]).to.have.property(\"balance_before\");","        pm.expect(b[0]).to.have.property(\"balance_after\");","        pm.expect(b[0].transaction_type).to.be.oneOf(","            [\"purchase\", \"consumption\", \"adjustment\", \"bonus\", \"refund\"]);","    }","});"]}}]},{"name":"Conciliar UN reporte (?reference=)","request":{"method":"GET","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/credits/transactions?reference={{report_id}}","host":["{{base_url}}"],"path":["api","v1","gateway","api","credits","transactions"],"query":[{"key":"reference","value":"{{report_id}}"}]},"description":"Los movimientos de ESE reporte y nada más: la reserva (`consumption` / `report_reservation`) y, si alguna fuente falló, la devolución (`refund` / `report_refund`).\n\n**Lo cobrado neto es la reserva menos la devolución (`amount` llega positivo en las dos), y tiene que coincidir con `credits_reserved - credits_refunded` del reporte.** Ésta es la conciliación que una pasarela necesita para cerrar una factura.\n\n`reference` en blanco o de más de 100 caracteres se rechaza con 422: un filtro que no puede matchear nada es un error, no una lista vacía."},"id":"creditos-conciliar","response":[{"name":"Conciliar UN reporte (?reference=) — ejemplo","originalRequest":{"method":"GET","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/credits/transactions?reference={{report_id}}","host":["{{base_url}}"],"path":["api","v1","gateway","api","credits","transactions"],"query":[{"key":"reference","value":"{{report_id}}"}]},"description":"Los movimientos de ESE reporte y nada más: la reserva (`consumption` / `report_reservation`) y, si alguna fuente falló, la devolución (`refund` / `report_refund`).\n\n**Lo cobrado neto es la reserva menos la devolución (`amount` llega positivo en las dos), y tiene que coincidir con `credits_reserved - credits_refunded` del reporte.** Ésta es la conciliación que una pasarela necesita para cerrar una factura.\n\n`reference` en blanco o de más de 100 caracteres se rechaza con 422: un filtro que no puede matchear nada es un error, no una lista vacía."},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"[\n  {\n    \"id\": \"9a1b2c3d-4e5f-6071-8293-a4b5c6d7e8f9\",\n    \"transaction_type\": \"refund\",\n    \"amount\": 1,\n    \"balance_before\": 4972,\n    \"balance_after\": 4973,\n    \"description\": \"Devolución por fuente fallida (dian-rut-estado)\",\n    \"reference\": \"3f2a8c10-5b7e-4d21-9a44-1c8e6b0d5f93\",\n    \"reference_type\": \"report_refund\",\n    \"metadata\": {\n      \"endpoints\": [\n        \"dian-rut-estado\"\n      ]\n    },\n    \"correlation_id\": \"mi-traza-9f3c\",\n    \"created_at\": \"2026-09-02T14:07:36Z\"\n  },\n  {\n    \"id\": \"1f2e3d4c-5b6a-7988-9a0b-1c2d3e4f5a6b\",\n    \"transaction_type\": \"consumption\",\n    \"amount\": 14,\n    \"balance_before\": 4986,\n    \"balance_after\": 4972,\n    \"description\": \"Reserva del reporte de verificación\",\n    \"reference\": \"3f2a8c10-5b7e-4d21-9a44-1c8e6b0d5f93\",\n    \"reference_type\": \"report_reservation\",\n    \"metadata\": {\n      \"sources\": 14\n    },\n    \"correlation_id\": \"mi-traza-9f3c\",\n    \"created_at\": \"2026-09-02T14:05:11Z\"\n  }\n]"}],"event":[{"listen":"prerequest","script":{"type":"text/javascript","exec":["if (!pm.variables.get(\"report_id\")) {","    console.warn(\"Falta la variable `report_id`: este request no se mandó.\");","    pm.execution.skipRequest();","}"]}},{"listen":"test","script":{"type":"text/javascript","exec":["pm.test(\"Todos los movimientos son del reporte pedido\", function () {","    pm.response.to.have.status(200);","    var b = pm.response.json();","    var esperado = pm.collectionVariables.get(\"report_id\");","    b.forEach(function (m) {","        pm.expect(m.reference, \"vino un movimiento de otro recurso\").to.eql(esperado);","    });","});","","// `amount` llega POSITIVO en los dos tipos: el signo lo da","// `transaction_type` (`consumption` cobra, `refund` devuelve).","var neto = null;","pm.test(\"El libro del reporte se suma por tipo de movimiento\", function () {","    pm.response.to.have.status(200);","    neto = pm.response.json().reduce(function (acc, m) {","        var a = Math.abs(Number(m.amount));","        if (m.transaction_type === \"consumption\") { return acc + a; }","        if (m.transaction_type === \"refund\") { return acc - a; }","        return acc;","    }, 0);","});","","if (neto !== null) {","    pm.sendRequest({","        url: pm.variables.replaceIn(\"{{base_url}}/api/v1/gateway/api/reports/{{report_id}}\"),","        method: \"GET\",","        header: { \"X-API-KEY\": pm.variables.replaceIn(\"{{api_key}}\") }","    }, function (err, res) {","        var r = (!err && res.code === 200) ? res.json() : null;","        var terminal = r !== null && [\"completed\", \"partial\", \"failed\"].indexOf(r.status) >= 0;","        // Con el reporte todavía corriendo, el libro y el reporte se leyeron","        // en momentos distintos: la comparación no prueba nada.","        var enCurso = r !== null && !terminal;","        if (enCurso) {","            console.log(\"El reporte todavía no cerró (\" + r.status + \"): volvé a correr la conciliación cuando cierre.\");","        }","        (enCurso ? pm.test.skip : pm.test)(\"El neto del libro es credits_reserved - credits_refunded del reporte cerrado\", function () {","            pm.expect(err).to.equal(null);","            pm.expect(res.code).to.eql(200);","            var cobrado = Number(r.credits_reserved) - Number(r.credits_refunded);","            pm.expect(neto, \"el libro no cuadra con lo que el reporte dice que cobró\").to.eql(cobrado);","        });","    });","}"]}}]}],"description":"El libro de créditos por organización: incluye los movimientos de la aplicación web y de otras keys, del mismo ambiente que la key. Sirve para cerrar una factura: cada reporte deja su reserva y, si alguna fuente falló, su devolución, las dos con `reference` = el `id` del reporte."},{"name":"7 · Webhooks (el aviso, en vez del polling)","item":[{"name":"Registrar un webhook","request":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/webhooks/","host":["{{base_url}}"],"path":["api","v1","gateway","api","webhooks"]},"description":"⚠ SÓLO CON KEY LIVE: registra un receptor real, que va a recibir los eventos de tu organización (de los dos ambientes). La URL sale de la variable `webhook_url`: con una key live y la variable vacía, este request NO sale. Con una key de prueba sale igual —para certificar el 403 de C1— contra `https://receptor.example/…`, un dominio reservado que no existe.\n\nDa de alta un receptor sin pasar por el panel. **Requiere una key live (`vf_live_`) con el scope `webhooks:manage`**; sin el scope, 403 con el nombre del scope adentro. El scope es opt-in y no se hereda: se pide para la key.\n\nCon una key de PRUEBA (`vf_test_`) la respuesta es 403 y el mensaje pide una `vf_live_`: los webhooks son de la organización y reciben también los eventos reales, así que el sandbox los puede ver pero no gestionar.\n\n⚠️ El `secret` se devuelve **una sola vez, acá**. Ningún GET posterior lo muestra; si lo perdés, rotalo.\n\nLa URL se valida contra SSRF: no puede resolver a loopback, RFC1918, link-local, CGNAT ni multicast, y `https://` es obligatorio en producción. Un `events` con un código que no exista se rechaza con 422 en vez de crear un receptor que nunca dispara.\n\nQUÉ LLEGA AL RECEPTOR\n· `event_type`: `report.completed`, `report.partial`, `report.failed`, `task.completed`.\n· El cuerpo es el MISMO `ReportResponse` que devuelve `GET /reports/{id}`, más `event_id`, `event_type`, `consent_id`, `correlation_id` y `evidence_sha256`.\n· `evidence_sha256` (así se llama — **no** `pdf_sha256`) es el SHA-256 del CONTENIDO de la evidencia que imprime el PDF, no de los bytes del archivo: el PDF se renderiza en cada descarga y dos renders no dan los mismos bytes. Viaja en `null` si el reporte cerró `failed`.\n· `correlation_id` es la `X-Correlation-ID` que mandaste al crear, saneada: sirve para atar tu traza a nuestro `id`.\n· `event_id` es la clave de deduplicación: el mismo evento puede llegar dos veces y hay que ignorarlo por ese id.\n· Firma: `X-VerifyCol-Signature`, HMAC-SHA256 sobre el cuerpo CRUDO. Durante la gracia de una rotación lleva DOS firmas separadas por coma: aceptá si CUALQUIERA coincide (la gracia dura 24 h).\n· `payload_mode: \"thin\"` saca del cuerpo los datos del titular (documento, nombre, `sources[].data`, narrativa): el detalle se trae con `GET /reports/{id}` usando la API key.","body":{"mode":"raw","raw":"{\n  \"name\": \"Producción — cierre de reportes\",\n  \"url\": \"{{webhook_url}}\",\n  \"events\": [\n    \"report.completed\",\n    \"report.partial\",\n    \"report.failed\"\n  ],\n  \"payload_mode\": \"thin\"\n}","options":{"raw":{"language":"json"}}}},"id":"webhook-alta","response":[{"name":"Registrar un webhook — ejemplo","originalRequest":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/webhooks/","host":["{{base_url}}"],"path":["api","v1","gateway","api","webhooks"]},"description":"⚠ SÓLO CON KEY LIVE: registra un receptor real, que va a recibir los eventos de tu organización (de los dos ambientes). La URL sale de la variable `webhook_url`: con una key live y la variable vacía, este request NO sale. Con una key de prueba sale igual —para certificar el 403 de C1— contra `https://receptor.example/…`, un dominio reservado que no existe.\n\nDa de alta un receptor sin pasar por el panel. **Requiere una key live (`vf_live_`) con el scope `webhooks:manage`**; sin el scope, 403 con el nombre del scope adentro. El scope es opt-in y no se hereda: se pide para la key.\n\nCon una key de PRUEBA (`vf_test_`) la respuesta es 403 y el mensaje pide una `vf_live_`: los webhooks son de la organización y reciben también los eventos reales, así que el sandbox los puede ver pero no gestionar.\n\n⚠️ El `secret` se devuelve **una sola vez, acá**. Ningún GET posterior lo muestra; si lo perdés, rotalo.\n\nLa URL se valida contra SSRF: no puede resolver a loopback, RFC1918, link-local, CGNAT ni multicast, y `https://` es obligatorio en producción. Un `events` con un código que no exista se rechaza con 422 en vez de crear un receptor que nunca dispara.\n\nQUÉ LLEGA AL RECEPTOR\n· `event_type`: `report.completed`, `report.partial`, `report.failed`, `task.completed`.\n· El cuerpo es el MISMO `ReportResponse` que devuelve `GET /reports/{id}`, más `event_id`, `event_type`, `consent_id`, `correlation_id` y `evidence_sha256`.\n· `evidence_sha256` (así se llama — **no** `pdf_sha256`) es el SHA-256 del CONTENIDO de la evidencia que imprime el PDF, no de los bytes del archivo: el PDF se renderiza en cada descarga y dos renders no dan los mismos bytes. Viaja en `null` si el reporte cerró `failed`.\n· `correlation_id` es la `X-Correlation-ID` que mandaste al crear, saneada: sirve para atar tu traza a nuestro `id`.\n· `event_id` es la clave de deduplicación: el mismo evento puede llegar dos veces y hay que ignorarlo por ese id.\n· Firma: `X-VerifyCol-Signature`, HMAC-SHA256 sobre el cuerpo CRUDO. Durante la gracia de una rotación lleva DOS firmas separadas por coma: aceptá si CUALQUIERA coincide (la gracia dura 24 h).\n· `payload_mode: \"thin\"` saca del cuerpo los datos del titular (documento, nombre, `sources[].data`, narrativa): el detalle se trae con `GET /reports/{id}` usando la API key.","body":{"mode":"raw","raw":"{\n  \"name\": \"Producción — cierre de reportes\",\n  \"url\": \"{{webhook_url}}\",\n  \"events\": [\n    \"report.completed\",\n    \"report.partial\",\n    \"report.failed\"\n  ],\n  \"payload_mode\": \"thin\"\n}","options":{"raw":{"language":"json"}}}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": \"5d2f7b31-9c04-4e88-b1a6-3e70f4c9a812\",\n  \"name\": \"Producción — cierre de reportes\",\n  \"url\": \"https://receptor.example/hooks/verifycol\",\n  \"secret\": \"whsec_9f3c1a7b5e2d4068b91c3f7a2d5e8014\",\n  \"events\": [\n    \"report.completed\",\n    \"report.partial\",\n    \"report.failed\"\n  ],\n  \"payload_mode\": \"thin\",\n  \"is_active\": true,\n  \"created_at\": \"2026-09-02T14:05:11Z\"\n}"}],"event":[{"listen":"prerequest","script":{"type":"text/javascript","exec":["// Un alta registra un receptor REAL: sólo con una URL que vos elegiste.","if (!pm.variables.get(\"webhook_url\")) {","    var esKeyDePrueba = (pm.variables.replaceIn(\"{{api_key}}\") || \"\").indexOf(\"vf_test_\") === 0;","    if (esKeyDePrueba) {","        // C1: con una vf_test_ responde 403 sin registrar nada; el","        // dominio reservado (RFC 2606) no resuelve a ningún lado.","        pm.variables.set(\"webhook_url\", \"https://receptor.example/hooks/verifycol\");","    } else {","        console.warn(\"Pegá la URL de TU receptor en la variable `webhook_url`: este request no se mandó.\");","        pm.execution.skipRequest();","    }","}"]}},{"listen":"test","script":{"type":"text/javascript","exec":["var esKeyDePrueba = (pm.variables.replaceIn(\"{{api_key}}\") || \"\").indexOf(\"vf_test_\") === 0;","if (esKeyDePrueba) {","    pm.test(\"Con una key de prueba (vf_test_): 403 que pide una vf_live_ (o 402 si el plan no trae webhooks)\", function () {","        pm.expect([403, 402]).to.include(pm.response.code);","        if (pm.response.code === 403) {","            pm.expect(pm.response.json().detail, \"el 403 tiene que decir con qué key repetir\").to.include(\"vf_live_\");","        }","    });","} else {","    pm.test(\"El alta responde 201, o 403 nombrando el scope que falta\", function () {","        pm.expect([201, 402, 403]).to.include(pm.response.code);","        if (pm.response.code === 403) {","            pm.expect(pm.response.json().detail).to.include(\"webhooks:manage\");","        }","    });","    ","    if (pm.response.code === 201) {","        pm.test(\"El alta devuelve el secret UNA sola vez y guarda el id\", function () {","            var b = pm.response.json();","            pm.expect(b.secret, \"sin secret no se puede verificar ninguna firma\").to.be.a(\"string\");","            pm.collectionVariables.set(\"webhook_id\", b.id);","        });","    }","}"]}}]},{"name":"Listar mis webhooks","request":{"method":"GET","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/webhooks/","host":["{{base_url}}"],"path":["api","v1","gateway","api","webhooks"]},"description":"Todos los de tu organización, **incluidos los pausados** — que es justo lo que este listado viene a resolver: a los 20 fallos consecutivos el receptor se auto-pausa y las entregas dejan de nacer. El `secret` nunca se devuelve."},"response":[{"name":"Listar mis webhooks — ejemplo","originalRequest":{"method":"GET","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/webhooks/","host":["{{base_url}}"],"path":["api","v1","gateway","api","webhooks"]},"description":"Todos los de tu organización, **incluidos los pausados** — que es justo lo que este listado viene a resolver: a los 20 fallos consecutivos el receptor se auto-pausa y las entregas dejan de nacer. El `secret` nunca se devuelve."},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"items\": [\n    {\n      \"id\": \"5d2f7b31-9c04-4e88-b1a6-3e70f4c9a812\",\n      \"name\": \"Producción — cierre de reportes\",\n      \"url\": \"https://receptor.example/hooks/verifycol\",\n      \"events\": [\n        \"report.completed\",\n        \"report.partial\",\n        \"report.failed\"\n      ],\n      \"payload_mode\": \"thin\",\n      \"is_active\": true,\n      \"consecutive_failures\": 0,\n      \"last_success_at\": \"2026-09-02T14:07:36Z\",\n      \"last_failure_at\": null,\n      \"created_at\": \"2026-09-02T14:05:11Z\"\n    },\n    {\n      \"id\": \"0b8e5a17-4c92-4d31-a7f6-2e15c9d8b043\",\n      \"name\": \"Staging\",\n      \"url\": \"https://receptor.example/hooks/verifycol\",\n      \"events\": [\n        \"report.completed\",\n        \"report.partial\",\n        \"report.failed\"\n      ],\n      \"payload_mode\": \"thin\",\n      \"is_active\": false,\n      \"consecutive_failures\": 20,\n      \"last_success_at\": null,\n      \"last_failure_at\": \"2026-09-02T14:07:36Z\",\n      \"created_at\": \"2026-09-02T14:05:11Z\"\n    }\n  ],\n  \"total\": 2\n}"}],"event":[{"listen":"test","script":{"type":"text/javascript","exec":["pm.test(\"El listado incluye los pausados\", function () {","    pm.response.to.have.status(200);","    var b = pm.response.json();","    pm.expect(b.items).to.be.an(\"array\");","    pm.expect(b).to.have.property(\"total\");","});"]}}]},{"name":"Ver un webhook y su diagnóstico","request":{"method":"GET","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/webhooks/{{webhook_id}}","host":["{{base_url}}"],"path":["api","v1","gateway","api","webhooks","{{webhook_id}}"]},"description":"`is_active`, `consecutive_failures`, `last_failure_at` y `last_success_at`: el diagnóstico que antes sólo veía el panel.\n\nA los 20 fallos consecutivos se auto-pausa. Si reactivás dentro de **72 horas**, las entregas de los reportes que cerraron durante la pausa se regeneran solas."},"response":[{"name":"Ver un webhook y su diagnóstico — ejemplo","originalRequest":{"method":"GET","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/webhooks/{{webhook_id}}","host":["{{base_url}}"],"path":["api","v1","gateway","api","webhooks","{{webhook_id}}"]},"description":"`is_active`, `consecutive_failures`, `last_failure_at` y `last_success_at`: el diagnóstico que antes sólo veía el panel.\n\nA los 20 fallos consecutivos se auto-pausa. Si reactivás dentro de **72 horas**, las entregas de los reportes que cerraron durante la pausa se regeneran solas."},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": \"5d2f7b31-9c04-4e88-b1a6-3e70f4c9a812\",\n  \"name\": \"Producción — cierre de reportes\",\n  \"url\": \"https://receptor.example/hooks/verifycol\",\n  \"events\": [\n    \"report.completed\",\n    \"report.partial\",\n    \"report.failed\"\n  ],\n  \"payload_mode\": \"thin\",\n  \"is_active\": false,\n  \"consecutive_failures\": 20,\n  \"last_success_at\": null,\n  \"last_failure_at\": \"2026-09-02T14:07:36Z\",\n  \"created_at\": \"2026-09-02T14:05:11Z\"\n}"}],"id":"webhook-ver","event":[{"listen":"prerequest","script":{"type":"text/javascript","exec":["if (!pm.variables.get(\"webhook_id\")) {","    console.warn(\"Falta la variable `webhook_id`: este request no se mandó.\");","    pm.execution.skipRequest();","}"]}},{"listen":"test","script":{"type":"text/javascript","exec":["pm.test(\"El diagnóstico dice si está pausado y por qué\", function () {","    pm.response.to.have.status(200);","    var b = pm.response.json();","    pm.expect(b).to.have.property(\"is_active\");","    pm.expect(b.consecutive_failures).to.be.a(\"number\");","});"]}}]},{"name":"Reactivar un webhook pausado","request":{"method":"PATCH","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/webhooks/{{webhook_id}}","host":["{{base_url}}"],"path":["api","v1","gateway","api","webhooks","{{webhook_id}}"]},"description":"Lo ÚNICO que este canal puede cambiar es `is_active`. Mandar `url`, `name` o `events` responde **422** en vez de ignorarlo en silencio: desviar la URL de destino con una key filtrada mandaría todos tus eventos a un receptor ajeno.\n\nReactivar resetea `consecutive_failures` a 0 **y vuelve a encolar** las entregas que la pausa mató en las últimas 72 h. Las que murieron agotando sus reintentos NO reviven acá: para ésas está `Reintentar una entrega`.\n\nNo pide el scope `webhooks:manage`, pero **sí una key live (`vf_live_`)**: con una key de prueba responde 403 y el mensaje pide una `vf_live_`.","body":{"mode":"raw","raw":"{\n  \"is_active\": true\n}","options":{"raw":{"language":"json"}}}},"id":"webhook-reactivar","response":[{"name":"Reactivar un webhook pausado — ejemplo","originalRequest":{"method":"PATCH","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/webhooks/{{webhook_id}}","host":["{{base_url}}"],"path":["api","v1","gateway","api","webhooks","{{webhook_id}}"]},"description":"Lo ÚNICO que este canal puede cambiar es `is_active`. Mandar `url`, `name` o `events` responde **422** en vez de ignorarlo en silencio: desviar la URL de destino con una key filtrada mandaría todos tus eventos a un receptor ajeno.\n\nReactivar resetea `consecutive_failures` a 0 **y vuelve a encolar** las entregas que la pausa mató en las últimas 72 h. Las que murieron agotando sus reintentos NO reviven acá: para ésas está `Reintentar una entrega`.\n\nNo pide el scope `webhooks:manage`, pero **sí una key live (`vf_live_`)**: con una key de prueba responde 403 y el mensaje pide una `vf_live_`.","body":{"mode":"raw","raw":"{\n  \"is_active\": true\n}","options":{"raw":{"language":"json"}}}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": \"5d2f7b31-9c04-4e88-b1a6-3e70f4c9a812\",\n  \"name\": \"Producción — cierre de reportes\",\n  \"url\": \"https://receptor.example/hooks/verifycol\",\n  \"events\": [\n    \"report.completed\",\n    \"report.partial\",\n    \"report.failed\"\n  ],\n  \"payload_mode\": \"thin\",\n  \"is_active\": true,\n  \"consecutive_failures\": 0,\n  \"last_success_at\": \"2026-09-02T14:07:36Z\",\n  \"last_failure_at\": null,\n  \"created_at\": \"2026-09-02T14:05:11Z\"\n}"}],"event":[{"listen":"prerequest","script":{"type":"text/javascript","exec":["if (!pm.variables.get(\"webhook_id\")) {","    var esKeyDePrueba = (pm.variables.replaceIn(\"{{api_key}}\") || \"\").indexOf(\"vf_test_\") === 0;","    if (esKeyDePrueba) {","        // C1: con una vf_test_ la respuesta es 403 sin mirar el id.","        pm.variables.set(\"webhook_id\", \"00000000-0000-0000-0000-000000000000\");","    } else {","        console.warn(\"Falta la variable `webhook_id`: este request no se mandó.\");","        pm.execution.skipRequest();","    }","}"]}},{"listen":"test","script":{"type":"text/javascript","exec":["var esKeyDePrueba = (pm.variables.replaceIn(\"{{api_key}}\") || \"\").indexOf(\"vf_test_\") === 0;","if (esKeyDePrueba) {","    pm.test(\"Con una key de prueba (vf_test_): 403 que pide una vf_live_\", function () {","        pm.response.to.have.status(403);","        pm.expect(pm.response.json().detail, \"el 403 tiene que decir con qué key repetir\").to.include(\"vf_live_\");","    });","} else {","    pm.test(\"Reactivar deja el contador de fallos en cero\", function () {","        pm.response.to.have.status(200);","        var b = pm.response.json();","        pm.expect(b.is_active).to.be.true;","        pm.expect(b.consecutive_failures,","            \"sin resetear, vuelve a pausarse en el primer fallo siguiente\").to.eql(0);","    });","}"]}}]},{"name":"Rotar el secret","request":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/webhooks/{{webhook_id}}/rotate-secret","host":["{{base_url}}"],"path":["api","v1","gateway","api","webhooks","{{webhook_id}}","rotate-secret"]},"description":"Genera un `secret` nuevo. **Requiere una key live (`vf_live_`) con el scope `webhooks:manage`**; sin el scope, 403 con el nombre del scope adentro. El scope es opt-in y no se hereda: se pide para la key.\n\nCon una key de PRUEBA (`vf_test_`) la respuesta es 403 y el mensaje pide una `vf_live_`: los webhooks son de la organización y reciben también los eventos reales, así que el sandbox los puede ver pero no gestionar.\n\n**El anterior NO deja de valer en el acto**: sigue firmando hasta `previous_secret_expires_at` (24 h). Mientras dure esa gracia, `X-VerifyCol-Signature` lleva las DOS firmas separadas por coma — verificá si CUALQUIERA coincide y desplegá el nuevo antes de esa fecha. Por eso rotar por API no tumba tu receptor.\n\n⚠️ El secret nuevo se muestra una sola vez, en esta respuesta."},"id":"webhook-rotar","response":[{"name":"Rotar el secret — ejemplo","originalRequest":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/webhooks/{{webhook_id}}/rotate-secret","host":["{{base_url}}"],"path":["api","v1","gateway","api","webhooks","{{webhook_id}}","rotate-secret"]},"description":"Genera un `secret` nuevo. **Requiere una key live (`vf_live_`) con el scope `webhooks:manage`**; sin el scope, 403 con el nombre del scope adentro. El scope es opt-in y no se hereda: se pide para la key.\n\nCon una key de PRUEBA (`vf_test_`) la respuesta es 403 y el mensaje pide una `vf_live_`: los webhooks son de la organización y reciben también los eventos reales, así que el sandbox los puede ver pero no gestionar.\n\n**El anterior NO deja de valer en el acto**: sigue firmando hasta `previous_secret_expires_at` (24 h). Mientras dure esa gracia, `X-VerifyCol-Signature` lleva las DOS firmas separadas por coma — verificá si CUALQUIERA coincide y desplegá el nuevo antes de esa fecha. Por eso rotar por API no tumba tu receptor.\n\n⚠️ El secret nuevo se muestra una sola vez, en esta respuesta."},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": \"5d2f7b31-9c04-4e88-b1a6-3e70f4c9a812\",\n  \"secret\": \"whsec_2d5e8014b91c3f7a9f3c1a7b5e204068\",\n  \"rotated_at\": \"2026-09-02T14:07:36Z\",\n  \"previous_secret_expires_at\": \"2026-09-03T14:07:36Z\"\n}"}],"event":[{"listen":"prerequest","script":{"type":"text/javascript","exec":["if (!pm.variables.get(\"webhook_id\")) {","    var esKeyDePrueba = (pm.variables.replaceIn(\"{{api_key}}\") || \"\").indexOf(\"vf_test_\") === 0;","    if (esKeyDePrueba) {","        // C1: con una vf_test_ la respuesta es 403 sin mirar el id.","        pm.variables.set(\"webhook_id\", \"00000000-0000-0000-0000-000000000000\");","    } else {","        console.warn(\"Falta la variable `webhook_id`: este request no se mandó.\");","        pm.execution.skipRequest();","    }","}"]}},{"listen":"test","script":{"type":"text/javascript","exec":["var esKeyDePrueba = (pm.variables.replaceIn(\"{{api_key}}\") || \"\").indexOf(\"vf_test_\") === 0;","if (esKeyDePrueba) {","    pm.test(\"Con una key de prueba (vf_test_): 403 que pide una vf_live_ (o 402 si el plan no trae webhooks)\", function () {","        pm.expect([403, 402]).to.include(pm.response.code);","        if (pm.response.code === 403) {","            pm.expect(pm.response.json().detail, \"el 403 tiene que decir con qué key repetir\").to.include(\"vf_live_\");","        }","    });","} else {","    pm.test(\"La rotación deja una gracia para el secret anterior\", function () {","        pm.response.to.have.status(200);","        var b = pm.response.json();","        pm.expect(b.secret).to.be.a(\"string\");","        pm.expect(b.previous_secret_expires_at,","            \"sin gracia, rotar tumba el receptor hasta que despliegue\").to.not.be.undefined;","    });","}"]}}]},{"name":"Ping de prueba firmado","request":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/webhooks/{{webhook_id}}/test","host":["{{base_url}}"],"path":["api","v1","gateway","api","webhooks","{{webhook_id}}","test"]},"description":"Manda UN evento sintético `webhook.test` firmado con el mismo esquema HMAC-SHA256 que una entrega real, para validar tu receptor sin esperar a una verificación.\n\n**No crea una entrega**: no cuenta para `consecutive_failures` ni para la auto-pausa, así que sirve para verificar un receptor arreglado ANTES de reactivarlo. La respuesta es siempre 200: `success` dice si el receptor contestó 2xx."},"response":[{"name":"Ping de prueba firmado — ejemplo","originalRequest":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/webhooks/{{webhook_id}}/test","host":["{{base_url}}"],"path":["api","v1","gateway","api","webhooks","{{webhook_id}}","test"]},"description":"Manda UN evento sintético `webhook.test` firmado con el mismo esquema HMAC-SHA256 que una entrega real, para validar tu receptor sin esperar a una verificación.\n\n**No crea una entrega**: no cuenta para `consecutive_failures` ni para la auto-pausa, así que sirve para verificar un receptor arreglado ANTES de reactivarlo. La respuesta es siempre 200: `success` dice si el receptor contestó 2xx."},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"status_code\": 200,\n  \"error\": null,\n  \"event_id\": \"c3a9f0e1-77b2-4d56-9e08-2f4a1b6c8d90\",\n  \"sent_at\": \"2026-09-02T14:07:36Z\"\n}"}],"id":"webhook-probar","event":[{"listen":"prerequest","script":{"type":"text/javascript","exec":["if (!pm.variables.get(\"webhook_id\")) {","    console.warn(\"Falta la variable `webhook_id`: este request no se mandó.\");","    pm.execution.skipRequest();","}"]}},{"listen":"test","script":{"type":"text/javascript","exec":["pm.test(\"El ping siempre responde 200 y dice si el receptor contestó\", function () {","    pm.response.to.have.status(200);","    pm.expect(pm.response.json().success).to.be.a(\"boolean\");","});"]}}]},{"name":"Historial de entregas","request":{"method":"GET","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/webhooks/{{webhook_id}}/deliveries?status=dead","host":["{{base_url}}"],"path":["api","v1","gateway","api","webhooks","{{webhook_id}}","deliveries"],"query":[{"key":"status","value":"dead"}]},"description":"Las entregas de este webhook, de la más reciente a la más vieja. Filtro opcional por `status`: `pending`, `retrying`, `delivered`, `failed` o `dead`.\n\n`dead` = se agotaron los reintentos del backoff. `failed` = la entrega se abortó por seguridad (por ejemplo, la URL empezó a resolver a una IP privada). Las dos se pueden reintentar a mano."},"response":[{"name":"Historial de entregas — ejemplo","originalRequest":{"method":"GET","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/webhooks/{{webhook_id}}/deliveries?status=dead","host":["{{base_url}}"],"path":["api","v1","gateway","api","webhooks","{{webhook_id}}","deliveries"],"query":[{"key":"status","value":"dead"}]},"description":"Las entregas de este webhook, de la más reciente a la más vieja. Filtro opcional por `status`: `pending`, `retrying`, `delivered`, `failed` o `dead`.\n\n`dead` = se agotaron los reintentos del backoff. `failed` = la entrega se abortó por seguridad (por ejemplo, la URL empezó a resolver a una IP privada). Las dos se pueden reintentar a mano."},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"items\": [\n    {\n      \"id\": \"e7c0a4b2-1d63-4f95-8a27-b0d1e6f38c54\",\n      \"webhook_endpoint_id\": \"5d2f7b31-9c04-4e88-b1a6-3e70f4c9a812\",\n      \"event_id\": \"c3a9f0e1-77b2-4d56-9e08-2f4a1b6c8d90\",\n      \"event_type\": \"report.completed\",\n      \"source_task_id\": null,\n      \"source_report_id\": \"3f2a8c10-5b7e-4d21-9a44-1c8e6b0d5f93\",\n      \"status\": \"dead\",\n      \"attempt_count\": 8,\n      \"max_attempts\": 8,\n      \"last_attempt_at\": \"2026-09-02T14:07:36Z\",\n      \"next_retry_at\": null,\n      \"response_code\": 500,\n      \"error_message\": \"HTTP 500\",\n      \"created_at\": \"2026-09-02T14:07:36Z\"\n    }\n  ],\n  \"total\": 1\n}"}],"id":"webhook-entregas","event":[{"listen":"prerequest","script":{"type":"text/javascript","exec":["if (!pm.variables.get(\"webhook_id\")) {","    console.warn(\"Falta la variable `webhook_id`: este request no se mandó.\");","    pm.execution.skipRequest();","}"]}},{"listen":"test","script":{"type":"text/javascript","exec":["pm.test(\"Las entregas dicen cuántos intentos llevan\", function () {","    pm.response.to.have.status(200);","    var b = pm.response.json();","    pm.expect(b.items).to.be.an(\"array\");","    if (b.items.length) {","        pm.collectionVariables.set(\"delivery_id\", b.items[0].id);","        pm.expect(b.items[0].attempt_count).to.be.a(\"number\");","    }","});"]}}]},{"name":"Reintentar una entrega","request":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/webhooks/deliveries/{{delivery_id}}/retry","host":["{{base_url}}"],"path":["api","v1","gateway","api","webhooks","deliveries","{{delivery_id}}","retry"]},"description":"Agenda un reintento de una entrega fallida o muerta.\n\n**NO despacha en línea** y **NO resetea `attempt_count`**: el envío real lo hace el job de despacho en su próxima corrida, con la revalidación anti-SSRF, el IP-pinning y el lock anti doble-envío.\n\n409 si esa entrega ya se había entregado.\n\nNo pide el scope `webhooks:manage`, pero **sí una key live (`vf_live_`)**: con una key de prueba responde 403 y el mensaje pide una `vf_live_`."},"id":"webhook-reintentar","response":[{"name":"Reintentar una entrega — ejemplo","originalRequest":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/webhooks/deliveries/{{delivery_id}}/retry","host":["{{base_url}}"],"path":["api","v1","gateway","api","webhooks","deliveries","{{delivery_id}}","retry"]},"description":"Agenda un reintento de una entrega fallida o muerta.\n\n**NO despacha en línea** y **NO resetea `attempt_count`**: el envío real lo hace el job de despacho en su próxima corrida, con la revalidación anti-SSRF, el IP-pinning y el lock anti doble-envío.\n\n409 si esa entrega ya se había entregado.\n\nNo pide el scope `webhooks:manage`, pero **sí una key live (`vf_live_`)**: con una key de prueba responde 403 y el mensaje pide una `vf_live_`."},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": \"e7c0a4b2-1d63-4f95-8a27-b0d1e6f38c54\",\n  \"webhook_endpoint_id\": \"5d2f7b31-9c04-4e88-b1a6-3e70f4c9a812\",\n  \"event_id\": \"c3a9f0e1-77b2-4d56-9e08-2f4a1b6c8d90\",\n  \"event_type\": \"report.completed\",\n  \"source_task_id\": null,\n  \"source_report_id\": \"3f2a8c10-5b7e-4d21-9a44-1c8e6b0d5f93\",\n  \"status\": \"retrying\",\n  \"attempt_count\": 8,\n  \"max_attempts\": 8,\n  \"last_attempt_at\": \"2026-09-02T14:07:36Z\",\n  \"next_retry_at\": \"2026-09-02T14:10:00Z\",\n  \"response_code\": 500,\n  \"error_message\": \"HTTP 500\",\n  \"created_at\": \"2026-09-02T14:07:36Z\"\n}"}],"event":[{"listen":"prerequest","script":{"type":"text/javascript","exec":["if (!pm.variables.get(\"delivery_id\")) {","    var esKeyDePrueba = (pm.variables.replaceIn(\"{{api_key}}\") || \"\").indexOf(\"vf_test_\") === 0;","    if (esKeyDePrueba) {","        // C1: con una vf_test_ la respuesta es 403 sin mirar el id.","        pm.variables.set(\"delivery_id\", \"00000000-0000-0000-0000-000000000000\");","    } else {","        console.warn(\"Falta la variable `delivery_id`: este request no se mandó.\");","        pm.execution.skipRequest();","    }","}"]}},{"listen":"test","script":{"type":"text/javascript","exec":["var esKeyDePrueba = (pm.variables.replaceIn(\"{{api_key}}\") || \"\").indexOf(\"vf_test_\") === 0;","if (esKeyDePrueba) {","    pm.test(\"Con una key de prueba (vf_test_): 403 que pide una vf_live_ (o 402 si el plan no trae webhooks)\", function () {","        pm.expect([403, 402]).to.include(pm.response.code);","        if (pm.response.code === 403) {","            pm.expect(pm.response.json().detail, \"el 403 tiene que decir con qué key repetir\").to.include(\"vf_live_\");","        }","    });","} else {","    pm.test(\"El reintento agenda, no despacha, y no borra los intentos previos\", function () {","        pm.expect([200, 409]).to.include(pm.response.code);","        if (pm.response.code === 409) { return; }","        var b = pm.response.json();","        pm.expect(b.status).to.be.oneOf([\"pending\", \"retrying\"]);","        pm.expect(b.attempt_count, \"resetear los intentos esquivaría el tope del backoff\").to.be.above(0);","    });","}"]}}]},{"name":"Eliminar un webhook","request":{"method":"DELETE","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/webhooks/{{webhook_id}}","host":["{{base_url}}"],"path":["api","v1","gateway","api","webhooks","{{webhook_id}}"]},"description":"Borra el receptor y sus entregas. **Requiere una key live (`vf_live_`) con el scope `webhooks:manage`**; sin el scope, 403 con el nombre del scope adentro. El scope es opt-in y no se hereda: se pide para la key.\n\nCon una key de PRUEBA (`vf_test_`) la respuesta es 403 y el mensaje pide una `vf_live_`: los webhooks son de la organización y reciben también los eventos reales, así que el sandbox los puede ver pero no gestionar.\n\n**Es irreversible y casi nunca hace falta**: para dejar de recibir sin perder el historial, pausá con `PATCH {\"is_active\": false}`.\n\nResponde **204 sin cuerpo**."},"id":"webhook-borrar","response":[{"name":"Eliminar un webhook — ejemplo","originalRequest":{"method":"DELETE","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/webhooks/{{webhook_id}}","host":["{{base_url}}"],"path":["api","v1","gateway","api","webhooks","{{webhook_id}}"]},"description":"Borra el receptor y sus entregas. **Requiere una key live (`vf_live_`) con el scope `webhooks:manage`**; sin el scope, 403 con el nombre del scope adentro. El scope es opt-in y no se hereda: se pide para la key.\n\nCon una key de PRUEBA (`vf_test_`) la respuesta es 403 y el mensaje pide una `vf_live_`: los webhooks son de la organización y reciben también los eventos reales, así que el sandbox los puede ver pero no gestionar.\n\n**Es irreversible y casi nunca hace falta**: para dejar de recibir sin perder el historial, pausá con `PATCH {\"is_active\": false}`.\n\nResponde **204 sin cuerpo**."},"status":"No Content","code":204,"_postman_previewlanguage":"text","header":[],"body":""}],"event":[{"listen":"prerequest","script":{"type":"text/javascript","exec":["if (!pm.variables.get(\"webhook_id\")) {","    var esKeyDePrueba = (pm.variables.replaceIn(\"{{api_key}}\") || \"\").indexOf(\"vf_test_\") === 0;","    if (esKeyDePrueba) {","        // C1: con una vf_test_ la respuesta es 403 sin mirar el id.","        pm.variables.set(\"webhook_id\", \"00000000-0000-0000-0000-000000000000\");","    } else {","        console.warn(\"Falta la variable `webhook_id`: este request no se mandó.\");","        pm.execution.skipRequest();","    }","}"]}},{"listen":"test","script":{"type":"text/javascript","exec":["var esKeyDePrueba = (pm.variables.replaceIn(\"{{api_key}}\") || \"\").indexOf(\"vf_test_\") === 0;","if (esKeyDePrueba) {","    pm.test(\"Con una key de prueba (vf_test_): 403 que pide una vf_live_\", function () {","        pm.response.to.have.status(403);","        pm.expect(pm.response.json().detail, \"el 403 tiene que decir con qué key repetir\").to.include(\"vf_live_\");","    });","} else {","    pm.test(\"El borrado responde 204 y no devuelve cuerpo\", function () {","        pm.expect([204, 403, 404]).to.include(pm.response.code);","        if (pm.response.code === 204) {","            pm.expect(pm.response.text()).to.eql(\"\");","        }","    });","}"]}}]}],"description":"Un receptor propio te evita sondear: te avisamos cuando el reporte cierra.\n\nQUÉ KEY HACE FALTA\n· Ver, listar, probar (ping) y ver entregas: cualquier key de la organización, también la de prueba.\n· Reactivar o pausar y reintentar una entrega: una key live (`vf_live_`); no piden scope.\n· Dar de alta, rotar el secret y borrar: una key live (`vf_live_`) con el scope `webhooks:manage`.\nCon una key de prueba (`vf_test_`) toda la gestión responde 403 y el mensaje pide una `vf_live_`: los webhooks son de la organización y reciben los eventos de los DOS ambientes. Corrida con una key de prueba, esta carpeta certifica justamente ese 403.\n\nLos requests que necesitan `webhook_id` o `delivery_id` no salen si la variable está vacía (quedan fuera de la corrida con una nota en la consola).\n\nQUÉ LLEGA AL RECEPTOR\n· `event_type`: `report.completed`, `report.partial`, `report.failed`, `task.completed`.\n· El cuerpo es el MISMO `ReportResponse` que devuelve `GET /reports/{id}`, más `event_id`, `event_type`, `consent_id`, `correlation_id` y `evidence_sha256`.\n· `evidence_sha256` (así se llama — **no** `pdf_sha256`) es el SHA-256 del CONTENIDO de la evidencia que imprime el PDF, no de los bytes del archivo: el PDF se renderiza en cada descarga y dos renders no dan los mismos bytes. Viaja en `null` si el reporte cerró `failed`.\n· `correlation_id` es la `X-Correlation-ID` que mandaste al crear, saneada: sirve para atar tu traza a nuestro `id`.\n· `event_id` es la clave de deduplicación: el mismo evento puede llegar dos veces y hay que ignorarlo por ese id.\n· Firma: `X-VerifyCol-Signature`, HMAC-SHA256 sobre el cuerpo CRUDO. Durante la gracia de una rotación lleva DOS firmas separadas por coma: aceptá si CUALQUIERA coincide (la gracia dura 24 h).\n· `payload_mode: \"thin\"` saca del cuerpo los datos del titular (documento, nombre, `sources[].data`, narrativa): el detalle se trae con `GET /reports/{id}` usando la API key."},{"name":"8 · Errores (qué recibís y qué hacer)","item":[{"name":"401 — sin API key","request":{"method":"POST","header":[{"key":"Idempotency-Key","value":"{{$guid}}","type":"text","description":"Identifica ESTA solicitud. Un reintento por timeout de red con la misma clave devuelve el reporte original —con el header `Idempotent-Replayed: true`— en vez de crear y cobrar otro. Ventana: 24 h. `{{$guid}}` genera una clave nueva en cada envío, que es lo correcto para una solicitud nueva."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/reports/","host":["{{base_url}}"],"path":["api","v1","gateway","api","reports"]},"description":"Este request NO manda `X-API-KEY` a propósito: es el único error del canal que se reproduce sin preparar nada.\n\n`error.code` distingue los dos casos: `MISSING_API_KEY` (no mandaste el header) e `INVALID_API_KEY` (la mandaste y no vale o está vencida). **No son `UNAUTHORIZED`**: el 401 lo emite el middleware con códigos propios.\n\nDemasiados 401/403 seguidos desde la misma IP pasan a responder 429: adivinar claves cuesta cupo.\n\nTipos de documento aceptados: CC, CE, NIT, PA. OJO: el reporte acepta MENOS tipos que la consulta directa por fuente —que admite hasta CC, CE, NIT, PA, PPT y TI según la fuente—. Un tipo fuera de este conjunto NO omite una fuente: rechaza el reporte entero.","body":{"mode":"raw","raw":"{\n  \"tipo_documento\": \"CC\",\n  \"numero_documento\": \"900000003\",\n  \"data_authorization_declared\": true\n}","options":{"raw":{"language":"json"}}}},"id":"error-401","response":[{"name":"401 — sin API key — ejemplo","originalRequest":{"method":"POST","header":[{"key":"Idempotency-Key","value":"{{$guid}}","type":"text","description":"Identifica ESTA solicitud. Un reintento por timeout de red con la misma clave devuelve el reporte original —con el header `Idempotent-Replayed: true`— en vez de crear y cobrar otro. Ventana: 24 h. `{{$guid}}` genera una clave nueva en cada envío, que es lo correcto para una solicitud nueva."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/reports/","host":["{{base_url}}"],"path":["api","v1","gateway","api","reports"]},"description":"Este request NO manda `X-API-KEY` a propósito: es el único error del canal que se reproduce sin preparar nada.\n\n`error.code` distingue los dos casos: `MISSING_API_KEY` (no mandaste el header) e `INVALID_API_KEY` (la mandaste y no vale o está vencida). **No son `UNAUTHORIZED`**: el 401 lo emite el middleware con códigos propios.\n\nDemasiados 401/403 seguidos desde la misma IP pasan a responder 429: adivinar claves cuesta cupo.\n\nTipos de documento aceptados: CC, CE, NIT, PA. OJO: el reporte acepta MENOS tipos que la consulta directa por fuente —que admite hasta CC, CE, NIT, PA, PPT y TI según la fuente—. Un tipo fuera de este conjunto NO omite una fuente: rechaza el reporte entero.","body":{"mode":"raw","raw":"{\n  \"tipo_documento\": \"CC\",\n  \"numero_documento\": \"900000003\",\n  \"data_authorization_declared\": true\n}","options":{"raw":{"language":"json"}}}},"status":"Unauthorized","code":401,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"detail\": \"Se requiere header X-API-KEY para acceder a este recurso\",\n  \"success\": false,\n  \"error\": {\n    \"code\": \"MISSING_API_KEY\",\n    \"message\": \"Se requiere header X-API-KEY para acceder a este recurso\"\n  }\n}"}],"event":[{"listen":"test","script":{"type":"text/javascript","exec":["pm.test(\"Sin la key: 401 con MISSING_API_KEY\", function () {","    pm.response.to.have.status(401);","    var e = pm.response.json().error;","    pm.expect(e.code).to.be.oneOf([\"MISSING_API_KEY\", \"INVALID_API_KEY\"]);","    pm.expect(pm.response.json().detail, \"el sobre del canal siempre trae detail\").to.be.a(\"string\");","});"]}}]},{"name":"402 — sin créditos","request":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"Idempotency-Key","value":"{{$guid}}","type":"text","description":"Identifica ESTA solicitud. Un reintento por timeout de red con la misma clave devuelve el reporte original —con el header `Idempotent-Replayed: true`— en vez de crear y cobrar otro. Ventana: 24 h. `{{$guid}}` genera una clave nueva en cada envío, que es lo correcto para una solicitud nueva."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/reports/","host":["{{base_url}}"],"path":["api","v1","gateway","api","reports"]},"description":"Se responde cuando el saldo no alcanza. **No cobra nada y LIBERA la `Idempotency-Key`**: recargás créditos, mandás la MISMA clave y responde 201. Un rechazo por saldo no puede dejar el UUID quemado 24 h.\n\nPara saber si vas a caer acá ANTES de intentar: `POST /reports/estimate` devuelve `can_proceed` y, si es `false`, `blockers` con `insufficient_credits` adentro.\n\nCon una key de PRUEBA (`vf_test_`) en `api_key` se reproduce sin preparar nada: el sujeto 900000009 del banco del sandbox responde 402 aunque haya saldo. Con una key live necesita una organización sin saldo; si hay, este request responde 201 (y cobra UNA fuente) y las afirmaciones quedan en `skipped`.\n\nTipos de documento aceptados: CC, CE, NIT, PA. OJO: el reporte acepta MENOS tipos que la consulta directa por fuente —que admite hasta CC, CE, NIT, PA, PPT y TI según la fuente—. Un tipo fuera de este conjunto NO omite una fuente: rechaza el reporte entero.","body":{"mode":"raw","raw":"{\n  \"tipo_documento\": \"CC\",\n  \"numero_documento\": \"900000009\",\n  \"data_authorization_declared\": true,\n  \"selected_endpoints\": [\n    \"contraloria-natural\"\n  ]\n}","options":{"raw":{"language":"json"}}}},"id":"error-402","response":[{"name":"402 — sin créditos — ejemplo","originalRequest":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"Idempotency-Key","value":"{{$guid}}","type":"text","description":"Identifica ESTA solicitud. Un reintento por timeout de red con la misma clave devuelve el reporte original —con el header `Idempotent-Replayed: true`— en vez de crear y cobrar otro. Ventana: 24 h. `{{$guid}}` genera una clave nueva en cada envío, que es lo correcto para una solicitud nueva."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/reports/","host":["{{base_url}}"],"path":["api","v1","gateway","api","reports"]},"description":"Se responde cuando el saldo no alcanza. **No cobra nada y LIBERA la `Idempotency-Key`**: recargás créditos, mandás la MISMA clave y responde 201. Un rechazo por saldo no puede dejar el UUID quemado 24 h.\n\nPara saber si vas a caer acá ANTES de intentar: `POST /reports/estimate` devuelve `can_proceed` y, si es `false`, `blockers` con `insufficient_credits` adentro.\n\nCon una key de PRUEBA (`vf_test_`) en `api_key` se reproduce sin preparar nada: el sujeto 900000009 del banco del sandbox responde 402 aunque haya saldo. Con una key live necesita una organización sin saldo; si hay, este request responde 201 (y cobra UNA fuente) y las afirmaciones quedan en `skipped`.\n\nTipos de documento aceptados: CC, CE, NIT, PA. OJO: el reporte acepta MENOS tipos que la consulta directa por fuente —que admite hasta CC, CE, NIT, PA, PPT y TI según la fuente—. Un tipo fuera de este conjunto NO omite una fuente: rechaza el reporte entero.","body":{"mode":"raw","raw":"{\n  \"tipo_documento\": \"CC\",\n  \"numero_documento\": \"900000009\",\n  \"data_authorization_declared\": true,\n  \"selected_endpoints\": [\n    \"contraloria-natural\"\n  ]\n}","options":{"raw":{"language":"json"}}}},"status":"Payment Required","code":402,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"detail\": \"Créditos insuficientes para ejecutar la verificación.\",\n  \"success\": false,\n  \"error\": {\n    \"code\": \"INSUFFICIENT_CREDITS\",\n    \"message\": \"Créditos insuficientes para ejecutar la verificación.\"\n  }\n}"}],"event":[{"listen":"test","script":{"type":"text/javascript","exec":["var sinSaldo = pm.response.code === 402;","var esKeyDePrueba = (pm.variables.replaceIn(\"{{api_key}}\") || \"\").indexOf(\"vf_test_\") === 0;","pm.test(\"402, o 201 si la organización tiene saldo (con una key de prueba, sólo 402)\", function () {","    pm.expect(esKeyDePrueba ? [402] : [402, 201]).to.include(pm.response.code);","});","(sinSaldo ? pm.test : pm.test.skip)(\"El 402 declara INSUFFICIENT_CREDITS\", function () {","    pm.expect(pm.response.json().error.code).to.eql(\"INSUFFICIENT_CREDITS\");","});","if (!sinSaldo) {","    console.log(\"Este caso necesita una key de prueba o una organización SIN créditos. Respondió \" + pm.response.code + \".\");","}"]}}]},{"name":"409 — conflicto de Idempotency-Key","request":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"Idempotency-Key","value":"{{idempotency_key}}","type":"text","description":"Identifica ESTA solicitud. Un reintento por timeout de red con la misma clave devuelve el reporte original —con el header `Idempotent-Replayed: true`— en vez de crear y cobrar otro. Ventana: 24 h. `{{$guid}}` genera una clave nueva en cada envío, que es lo correcto para una solicitud nueva."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/reports/","host":["{{base_url}}"],"path":["api","v1","gateway","api","reports"]},"description":"Reusa la `idempotency_key` de la colección con OTRO sujeto. Si esa clave ya se usó en las últimas 24 h con un cuerpo distinto, la respuesta es 409.\n\n`error.code` es `CONFLICT` en los dos casos; lo que los distingue —y lo que decide qué hacer— es `error.reason`:\n· `IDEMPOTENCY_CONFLICT` → la clave ya se usó con otro cuerpo. Esperar no lo resuelve y **no viene `Retry-After`**: emitÍ una clave nueva.\n· `IDEMPOTENCY_IN_PROGRESS` → hay una solicitud con esa clave corriendo ahora. Viene con `Retry-After`: reintentá con LA MISMA clave.\n\nLos seis casos completos, corribles, están en `4 · Certificación de idempotencia`.\n\nTipos de documento aceptados: CC, CE, NIT, PA. OJO: el reporte acepta MENOS tipos que la consulta directa por fuente —que admite hasta CC, CE, NIT, PA, PPT y TI según la fuente—. Un tipo fuera de este conjunto NO omite una fuente: rechaza el reporte entero.","body":{"mode":"raw","raw":"{\n  \"tipo_documento\": \"CC\",\n  \"numero_documento\": \"900000007\",\n  \"data_authorization_declared\": true,\n  \"selected_endpoints\": [\n    \"contraloria-natural\"\n  ]\n}","options":{"raw":{"language":"json"}}}},"id":"error-409","response":[{"name":"409 — conflicto de Idempotency-Key — ejemplo","originalRequest":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"Idempotency-Key","value":"{{idempotency_key}}","type":"text","description":"Identifica ESTA solicitud. Un reintento por timeout de red con la misma clave devuelve el reporte original —con el header `Idempotent-Replayed: true`— en vez de crear y cobrar otro. Ventana: 24 h. `{{$guid}}` genera una clave nueva en cada envío, que es lo correcto para una solicitud nueva."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/reports/","host":["{{base_url}}"],"path":["api","v1","gateway","api","reports"]},"description":"Reusa la `idempotency_key` de la colección con OTRO sujeto. Si esa clave ya se usó en las últimas 24 h con un cuerpo distinto, la respuesta es 409.\n\n`error.code` es `CONFLICT` en los dos casos; lo que los distingue —y lo que decide qué hacer— es `error.reason`:\n· `IDEMPOTENCY_CONFLICT` → la clave ya se usó con otro cuerpo. Esperar no lo resuelve y **no viene `Retry-After`**: emitÍ una clave nueva.\n· `IDEMPOTENCY_IN_PROGRESS` → hay una solicitud con esa clave corriendo ahora. Viene con `Retry-After`: reintentá con LA MISMA clave.\n\nLos seis casos completos, corribles, están en `4 · Certificación de idempotencia`.\n\nTipos de documento aceptados: CC, CE, NIT, PA. OJO: el reporte acepta MENOS tipos que la consulta directa por fuente —que admite hasta CC, CE, NIT, PA, PPT y TI según la fuente—. Un tipo fuera de este conjunto NO omite una fuente: rechaza el reporte entero.","body":{"mode":"raw","raw":"{\n  \"tipo_documento\": \"CC\",\n  \"numero_documento\": \"900000007\",\n  \"data_authorization_declared\": true,\n  \"selected_endpoints\": [\n    \"contraloria-natural\"\n  ]\n}","options":{"raw":{"language":"json"}}}},"status":"Conflict","code":409,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"detail\": \"Este Idempotency-Key ya se usó en las últimas 24 horas con un cuerpo distinto. Genere una clave nueva (UUID) por cada solicitud distinta.\",\n  \"success\": false,\n  \"error\": {\n    \"code\": \"CONFLICT\",\n    \"message\": \"Este Idempotency-Key ya se usó en las últimas 24 horas con un cuerpo distinto. Genere una clave nueva (UUID) por cada solicitud distinta.\",\n    \"reason\": \"IDEMPOTENCY_CONFLICT\"\n  }\n}"}],"event":[{"listen":"prerequest","script":{"type":"text/javascript","exec":["if (!pm.variables.get(\"idempotency_key\")) {","    console.warn(\"Falta la variable `idempotency_key`: este request no se mandó.\");","    pm.execution.skipRequest();","}"]}},{"listen":"test","script":{"type":"text/javascript","exec":["var hayConflicto = pm.response.code === 409;","pm.test(\"409, o la creación (201/202) si la clave no se había usado\", function () {","    pm.expect([409, 201, 202]).to.include(pm.response.code);","});","(hayConflicto ? pm.test : pm.test.skip)(\"El 409 trae CONFLICT y un reason que dice qué hacer\", function () {","    var e = pm.response.json().error;","    pm.expect(e.code).to.eql(\"CONFLICT\");","    pm.expect(e.reason,","        \"sin reason el integrador no sabe si esperar o cambiar la clave\").to.be.oneOf(","        [\"IDEMPOTENCY_CONFLICT\", \"IDEMPOTENCY_IN_PROGRESS\"]);","    if (e.reason === \"IDEMPOTENCY_CONFLICT\") {","        pm.expect(pm.response.headers.has(\"Retry-After\"),","            \"este 409 no se resuelve esperando\").to.be.false;","    }","});","if (!hayConflicto) {","    console.log(\"Mandá primero `5 · Consentimiento del titular` o fijá `idempotency_key`, y volvé a correr éste. Respondió \" + pm.response.code + \".\");","}"]}}]},{"name":"410 — reporte suprimido","request":{"method":"GET","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/reports/{{report_id}}","host":["{{base_url}}"],"path":["api","v1","gateway","api","reports","{{report_id}}"]},"description":"El reporte fue suprimido a solicitud del titular (Ley 1581): se conserva como evidencia, pero no se sirve ni su contenido, ni su PDF, ni sus documentos de soporte. **No reintentes.**\n\nLo responden el GET del reporte, su PDF y sus soportes, y también la CREACIÓN cuando reintentás con la misma `Idempotency-Key` de un reporte que después se suprimió: no se crea ni se cobra uno nuevo.\n\nUn reporte de otra organización o de otro ambiente responde 404, nunca 410: el 410 no delata reportes ajenos.\n\nNecesita un reporte suprimido en `report_id`; con uno vigente responde 200 y la afirmación del 410 queda en `skipped`."},"id":"error-410","response":[{"name":"410 — reporte suprimido — ejemplo","originalRequest":{"method":"GET","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/reports/{{report_id}}","host":["{{base_url}}"],"path":["api","v1","gateway","api","reports","{{report_id}}"]},"description":"El reporte fue suprimido a solicitud del titular (Ley 1581): se conserva como evidencia, pero no se sirve ni su contenido, ni su PDF, ni sus documentos de soporte. **No reintentes.**\n\nLo responden el GET del reporte, su PDF y sus soportes, y también la CREACIÓN cuando reintentás con la misma `Idempotency-Key` de un reporte que después se suprimió: no se crea ni se cobra uno nuevo.\n\nUn reporte de otra organización o de otro ambiente responde 404, nunca 410: el 410 no delata reportes ajenos.\n\nNecesita un reporte suprimido en `report_id`; con uno vigente responde 200 y la afirmación del 410 queda en `skipped`."},"status":"Gone","code":410,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"detail\": \"Este reporte fue suprimido a solicitud del titular (Ley 1581).\",\n  \"success\": false,\n  \"error\": {\n    \"code\": \"GONE\",\n    \"message\": \"Este reporte fue suprimido a solicitud del titular (Ley 1581).\"\n  }\n}"}],"event":[{"listen":"prerequest","script":{"type":"text/javascript","exec":["if (!pm.variables.get(\"report_id\")) {","    console.warn(\"Falta la variable `report_id`: este request no se mandó.\");","    pm.execution.skipRequest();","}"]}},{"listen":"test","script":{"type":"text/javascript","exec":["var suprimido = pm.response.code === 410;","pm.test(\"El reporte responde 200, o 410 si fue suprimido\", function () {","    pm.expect([200, 410]).to.include(pm.response.code);","});","(suprimido ? pm.test : pm.test.skip)(\"El 410 declara GONE: no se reintenta\", function () {","    pm.expect(pm.response.json().error.code).to.eql(\"GONE\");","});","if (!suprimido) {","    console.log(\"Este caso necesita un reporte suprimido en `report_id`. Respondió \" + pm.response.code + \".\");","}"]}}]},{"name":"422 — cuerpo inválido","request":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/reports/estimate","host":["{{base_url}}"],"path":["api","v1","gateway","api","reports","estimate"]},"description":"Manda una placa de 2 caracteres (el mínimo son 4). Va contra `estimate`, que no cobra ni consulta: el 422 se ve sin gastar un crédito.\n\n**Hay DOS códigos distintos de 422 y conviene programar los dos:**\n· `VALIDATION_ERROR` — falló el schema. `detail` es la LISTA de errores de Pydantic, con `loc` señalando el campo exacto.\n· `UNPROCESSABLE_ENTITY` — el cuerpo es válido pero la regla de negocio no (un `transaction_type` que no existe, un `origin` fuera de `quick|full`, un `reference` de más de 100 caracteres). `detail` es un string.\n\nEn los dos, `error.message` es siempre un texto de una línea: si sólo vas a mostrar algo, mostrá ése.\n\nTipos de documento aceptados: CC, CE, NIT, PA. OJO: el reporte acepta MENOS tipos que la consulta directa por fuente —que admite hasta CC, CE, NIT, PA, PPT y TI según la fuente—. Un tipo fuera de este conjunto NO omite una fuente: rechaza el reporte entero.","body":{"mode":"raw","raw":"{\n  \"tipo_documento\": \"CC\",\n  \"numero_documento\": \"900000003\",\n  \"data_authorization_declared\": true,\n  \"vehiculos\": [\n    {\n      \"placa\": \"!!\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"id":"error-422","response":[{"name":"422 — cuerpo inválido — ejemplo","originalRequest":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/reports/estimate","host":["{{base_url}}"],"path":["api","v1","gateway","api","reports","estimate"]},"description":"Manda una placa de 2 caracteres (el mínimo son 4). Va contra `estimate`, que no cobra ni consulta: el 422 se ve sin gastar un crédito.\n\n**Hay DOS códigos distintos de 422 y conviene programar los dos:**\n· `VALIDATION_ERROR` — falló el schema. `detail` es la LISTA de errores de Pydantic, con `loc` señalando el campo exacto.\n· `UNPROCESSABLE_ENTITY` — el cuerpo es válido pero la regla de negocio no (un `transaction_type` que no existe, un `origin` fuera de `quick|full`, un `reference` de más de 100 caracteres). `detail` es un string.\n\nEn los dos, `error.message` es siempre un texto de una línea: si sólo vas a mostrar algo, mostrá ése.\n\nTipos de documento aceptados: CC, CE, NIT, PA. OJO: el reporte acepta MENOS tipos que la consulta directa por fuente —que admite hasta CC, CE, NIT, PA, PPT y TI según la fuente—. Un tipo fuera de este conjunto NO omite una fuente: rechaza el reporte entero.","body":{"mode":"raw","raw":"{\n  \"tipo_documento\": \"CC\",\n  \"numero_documento\": \"900000003\",\n  \"data_authorization_declared\": true,\n  \"vehiculos\": [\n    {\n      \"placa\": \"!!\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"status":"Unprocessable Entity","code":422,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"detail\": [\n    {\n      \"type\": \"string_too_short\",\n      \"loc\": [\n        \"body\",\n        \"vehiculos\",\n        0,\n        \"placa\"\n      ],\n      \"msg\": \"String should have at least 4 characters\",\n      \"input\": \"!!\",\n      \"ctx\": {\n        \"min_length\": \"4\"\n      }\n    }\n  ],\n  \"success\": false,\n  \"error\": {\n    \"code\": \"VALIDATION_ERROR\",\n    \"message\": \"body.vehiculos.0.placa: String should have at least 4 characters\"\n  }\n}"}],"event":[{"listen":"test","script":{"type":"text/javascript","exec":["pm.test(\"El 422 de schema es VALIDATION_ERROR y detail es la lista de Pydantic\", function () {","    pm.response.to.have.status(422);","    var b = pm.response.json();","    pm.expect(b.error.code).to.be.oneOf([\"VALIDATION_ERROR\", \"UNPROCESSABLE_ENTITY\"]);","    if (b.error.code === \"VALIDATION_ERROR\") {","        pm.expect(b.detail, \"detail tiene que traer loc para saber QUÉ campo\").to.be.an(\"array\");","        pm.expect(b.detail[0]).to.have.property(\"loc\");","    }","    pm.expect(b.error.message).to.be.a(\"string\");","});"]}}]},{"name":"429 — cupo excedido","request":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/reports/estimate","host":["{{base_url}}"],"path":["api","v1","gateway","api","reports","estimate"]},"description":"Hay TRES limitadores y no elegís cuál te corta: por IP, por API key y por organización. Los tres responden el MISMO sobre, con `scope` (`ip`, `key` u `organization`) diciendo cuál fue.\n\n**`Retry-After` es la cuenta regresiva REAL**, no un valor fijo: obedecerlo reintenta en el momento justo. También viaja en el cuerpo como `retry_after`, y anidado en `error`. No existe `X-RateLimit-Reset`.\n\nLos techos vigentes están en la descripción de la colección; un 429 cobra 0 créditos.\n\nPara verlo, mandá este request en ráfaga con el Collection Runner. Si no llegás al tope, las afirmaciones quedan en `skipped`.\n\nTipos de documento aceptados: CC, CE, NIT, PA. OJO: el reporte acepta MENOS tipos que la consulta directa por fuente —que admite hasta CC, CE, NIT, PA, PPT y TI según la fuente—. Un tipo fuera de este conjunto NO omite una fuente: rechaza el reporte entero.","body":{"mode":"raw","raw":"{\n  \"tipo_documento\": \"CC\",\n  \"numero_documento\": \"900000003\",\n  \"data_authorization_declared\": true\n}","options":{"raw":{"language":"json"}}}},"id":"error-429","response":[{"name":"429 — cupo excedido — ejemplo","originalRequest":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/reports/estimate","host":["{{base_url}}"],"path":["api","v1","gateway","api","reports","estimate"]},"description":"Hay TRES limitadores y no elegís cuál te corta: por IP, por API key y por organización. Los tres responden el MISMO sobre, con `scope` (`ip`, `key` u `organization`) diciendo cuál fue.\n\n**`Retry-After` es la cuenta regresiva REAL**, no un valor fijo: obedecerlo reintenta en el momento justo. También viaja en el cuerpo como `retry_after`, y anidado en `error`. No existe `X-RateLimit-Reset`.\n\nLos techos vigentes están en la descripción de la colección; un 429 cobra 0 créditos.\n\nPara verlo, mandá este request en ráfaga con el Collection Runner. Si no llegás al tope, las afirmaciones quedan en `skipped`.\n\nTipos de documento aceptados: CC, CE, NIT, PA. OJO: el reporte acepta MENOS tipos que la consulta directa por fuente —que admite hasta CC, CE, NIT, PA, PPT y TI según la fuente—. Un tipo fuera de este conjunto NO omite una fuente: rechaza el reporte entero.","body":{"mode":"raw","raw":"{\n  \"tipo_documento\": \"CC\",\n  \"numero_documento\": \"900000003\",\n  \"data_authorization_declared\": true\n}","options":{"raw":{"language":"json"}}}},"status":"Too Many Requests","code":429,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"},{"key":"Retry-After","value":"37"},{"key":"X-RateLimit-Limit","value":"120"},{"key":"X-RateLimit-Remaining","value":"0"}],"body":"{\n  \"detail\": \"Rate limit de la key excedido (minute). Reintentá en 37 segundos.\",\n  \"success\": false,\n  \"error\": {\n    \"code\": \"RATE_LIMIT_EXCEEDED\",\n    \"message\": \"Rate limit de la key excedido (minute). Reintentá en 37 segundos.\"\n  },\n  \"retry_after\": 37,\n  \"scope\": \"key\"\n}"}],"event":[{"listen":"test","script":{"type":"text/javascript","exec":["var frenado = pm.response.code === 429;","pm.test(\"429, o 200 si no se llegó al tope\", function () {","    pm.expect([429, 200]).to.include(pm.response.code);","});","(frenado ? pm.test : pm.test.skip)(\"El 429 trae RATE_LIMIT_EXCEEDED, scope y Retry-After\", function () {","    var b = pm.response.json();","    pm.expect(b.error.code).to.eql(\"RATE_LIMIT_EXCEEDED\");","    pm.expect(b.scope, \"sin scope no sabés si subir tu concurrencia o pedir más cupo\").to.be.oneOf(","        [\"ip\", \"key\", \"organization\"]);","    pm.expect(pm.response.headers.has(\"Retry-After\"),","        \"sin Retry-After el cliente reintenta a ciegas\").to.be.true;","});","if (!frenado) {","    console.log(\"No se alcanzó el tope: mandá este request en ráfaga con el Collection Runner. Respondió \" + pm.response.code + \".\");","}"]}}]},{"name":"503 — saturado, reintentá","request":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"Idempotency-Key","value":"{{$guid}}","type":"text","description":"Identifica ESTA solicitud. Un reintento por timeout de red con la misma clave devuelve el reporte original —con el header `Idempotent-Replayed: true`— en vez de crear y cobrar otro. Ventana: 24 h. `{{$guid}}` genera una clave nueva en cada envío, que es lo correcto para una solicitud nueva."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/reports/","host":["{{base_url}}"],"path":["api","v1","gateway","api","reports"]},"description":"El sistema está saturado o una fuente no está disponible. Viene con `Retry-After` y **el 503 no cobra**: es un rechazo ANTES de reservar créditos.\n\nSe reintenta con LA MISMA `Idempotency-Key` sin riesgo de doble cobro. Es transitorio: no reemitas la clave.\n\n⚠ Con una key live (`vf_live_`), si no hay saturación, este request crea y cobra UNA fuente (`contraloria-natural`).\n\nTipos de documento aceptados: CC, CE, NIT, PA. OJO: el reporte acepta MENOS tipos que la consulta directa por fuente —que admite hasta CC, CE, NIT, PA, PPT y TI según la fuente—. Un tipo fuera de este conjunto NO omite una fuente: rechaza el reporte entero.","body":{"mode":"raw","raw":"{\n  \"tipo_documento\": \"CC\",\n  \"numero_documento\": \"900000003\",\n  \"data_authorization_declared\": true,\n  \"selected_endpoints\": [\n    \"contraloria-natural\"\n  ]\n}","options":{"raw":{"language":"json"}}}},"id":"error-503","response":[{"name":"503 — saturado, reintentá — ejemplo","originalRequest":{"method":"POST","header":[{"key":"X-API-KEY","value":"{{api_key}}","type":"text"},{"key":"Idempotency-Key","value":"{{$guid}}","type":"text","description":"Identifica ESTA solicitud. Un reintento por timeout de red con la misma clave devuelve el reporte original —con el header `Idempotent-Replayed: true`— en vez de crear y cobrar otro. Ventana: 24 h. `{{$guid}}` genera una clave nueva en cada envío, que es lo correcto para una solicitud nueva."},{"key":"Content-Type","value":"application/json","type":"text"}],"url":{"raw":"{{base_url}}/api/v1/gateway/api/reports/","host":["{{base_url}}"],"path":["api","v1","gateway","api","reports"]},"description":"El sistema está saturado o una fuente no está disponible. Viene con `Retry-After` y **el 503 no cobra**: es un rechazo ANTES de reservar créditos.\n\nSe reintenta con LA MISMA `Idempotency-Key` sin riesgo de doble cobro. Es transitorio: no reemitas la clave.\n\n⚠ Con una key live (`vf_live_`), si no hay saturación, este request crea y cobra UNA fuente (`contraloria-natural`).\n\nTipos de documento aceptados: CC, CE, NIT, PA. OJO: el reporte acepta MENOS tipos que la consulta directa por fuente —que admite hasta CC, CE, NIT, PA, PPT y TI según la fuente—. Un tipo fuera de este conjunto NO omite una fuente: rechaza el reporte entero.","body":{"mode":"raw","raw":"{\n  \"tipo_documento\": \"CC\",\n  \"numero_documento\": \"900000003\",\n  \"data_authorization_declared\": true,\n  \"selected_endpoints\": [\n    \"contraloria-natural\"\n  ]\n}","options":{"raw":{"language":"json"}}}},"status":"Service Unavailable","code":503,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"},{"key":"Retry-After","value":"30"}],"body":"{\n  \"detail\": \"El sistema está procesando el máximo de verificaciones simultáneas. Reintente en unos segundos.\",\n  \"success\": false,\n  \"error\": {\n    \"code\": \"SERVICE_UNAVAILABLE\",\n    \"message\": \"El sistema está procesando el máximo de verificaciones simultáneas. Reintente en unos segundos.\"\n  }\n}"}],"event":[{"listen":"test","script":{"type":"text/javascript","exec":["var saturado = pm.response.code === 503;","pm.test(\"503, o la creación (201, o 202 si tu organización exige el titular) si no hay saturación\", function () {","    pm.expect([503, 201, 202]).to.include(pm.response.code);","});","(saturado ? pm.test : pm.test.skip)(\"El 503 trae SERVICE_UNAVAILABLE y Retry-After\", function () {","    pm.expect(pm.response.json().error.code).to.eql(\"SERVICE_UNAVAILABLE\");","    pm.expect(pm.response.headers.has(\"Retry-After\"),","        \"un 503 sin Retry-After deja al cliente reintentando a ciegas\").to.be.true;","});","if (!saturado) {","    console.log(\"El sistema no está saturado ahora. Respondió \" + pm.response.code + \".\");","}"]}}]}],"description":"El canal responde SIEMPRE la misma forma: `{detail, success: false, error: {code, message}}`. `detail` es lo que lee un cliente hecho contra FastAPI; `error.code` es el código ESTABLE contra el que se programa.\n\nEl 401 y el 422 se reproducen sin preparar nada, y el 402 también con una key de prueba (`vf_test_`) en `api_key`: el sujeto 900000009 del banco del sandbox lo fuerza. Los demás traen su ejemplo real y afirmaciones que quedan en `skipped` —con una nota en la consola— si el ambiente no está en ese estado: un rojo por un ambiente sin preparar entrena a ignorar los rojos."}]}