{
  "openapi": "3.1.0",
  "info": {
    "title": "PlacApi API",
    "version": "1.0.0",
    "description": "API REST para consolidar consultas de información vehicular de Colombia (RUNT, SOAT, tecnomecánica, SIMIT, antecedentes, impuestos, FASECOLDA y pico y placa) y licencias de conducción. PlacApi no es una entidad oficial del Gobierno colombiano.",
    "termsOfService": "https://placapi.com/terminos",
    "contact": {
      "name": "Soporte PlacApi",
      "email": "soporte@placapi.com",
      "url": "https://placapi.com/docs"
    },
    "license": {
      "name": "Términos de PlacApi",
      "url": "https://placapi.com/terminos"
    },
    "x-pricing": {
      "model": "prepaid-credits",
      "pricePerQuery": 349,
      "currency": "COP",
      "note": "Se cobra el número de créditos de cada endpoint (x-credits) cuando la consulta devuelve datos: 1 crédito la mayoría, 2 en consulta-full. Una consulta sin resultado (404) trae 10 gratis por mes y por cada código de sin-resultado, con cuotas independientes; a partir de la 11 de ese código cobra como una consulta normal. Repetir la misma consulta (misma placa y documento) dentro de la ventana de caché se responde con fromCache: true y NO vuelve a cobrar; la ventana va de 24h (datos del vehículo) a 30 días según la fuente. Excepción: consulta-full siempre cobra sus 2 créditos."
    }
  },
  "servers": [
    {
      "url": "https://placapi.com/api",
      "description": "Producción"
    }
  ],
  "paths": {
    "/consulta-full": {
      "post": {
        "operationId": "consulta-full",
        "summary": "Consulta full (todo en uno)",
        "description": "Todo el conjunto de fuentes en UNA sola llamada: bundle vehicular completo (RUNT, SOAT, tecnomecánica, antecedentes, multas SIMIT, impuesto, avalúo FASECOLDA y pico y placa) MÁS la licencia de conducción del propietario (por la misma cédula). Con `ciudad` o `lat`/`lng` (geolocaliza la ciudad; manda sobre `ciudad`) el pico y placa se filtra a esa ciudad y agrega `picoYPlaca.ubicacion`; sin ubicación trae todas las ciudades monitoreadas. El tipo de vehículo se detecta solo desde la clase RUNT; el dígito de placa evaluado lo fija cada ciudad y viene en `digitoPlaca` (por defecto primero para moto, último para carro). Cuesta 2 créditos. Costo: 2 créditos por consulta con datos.",
        "x-credits": 2,
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "placa",
                  "docType",
                  "docNumber"
                ],
                "properties": {
                  "placa": {
                    "type": "string",
                    "example": "ABC123",
                    "description": "Placa del vehículo. 5 a 7 caracteres alfanuméricos: cubre AAA000, AAA00A y los formatos menos comunes (AAA00, AAAA00). Los guiones y espacios se ignoran."
                  },
                  "docType": {
                    "type": "string",
                    "example": "CC",
                    "description": "Tipo de documento del propietario (CC, CE, NIT, PA, TI, CD, PPT, RC; PAS se normaliza a PA y P.P.T./P.P. a PPT). Con NIT no se consulta licencia: `licencia` viene null.",
                    "enum": [
                      "CC",
                      "CE",
                      "NIT",
                      "PA",
                      "TI",
                      "CD",
                      "PPT",
                      "RC"
                    ]
                  },
                  "docNumber": {
                    "type": "string",
                    "example": "1020304050",
                    "description": "Número de documento del propietario. Alias aceptado: `doc`."
                  },
                  "primerApellido": {
                    "type": "string",
                    "example": "PÉREZ",
                    "description": "Primer apellido del propietario. Solo afecta al bloque `licencia`: la fuente oficial lo exige desde el 6-ago-2026 y sin él ese bloque llega con `code: \"apellido_requerido\"`. El bundle vehicular no lo necesita y se entrega igual. Alias aceptado: `apellido`."
                  },
                  "ciudad": {
                    "type": "string",
                    "example": "Bogotá",
                    "description": "Filtra el pico y placa a esta ciudad (ej. Bogotá)."
                  },
                  "lat": {
                    "type": "number",
                    "example": 4.65,
                    "description": "Latitud; requiere lng. Geolocaliza la ciudad del pico y placa y manda sobre `ciudad`."
                  },
                  "lng": {
                    "type": "number",
                    "example": -74.1,
                    "description": "Longitud; requiere lat."
                  },
                  "refresh": {
                    "type": "boolean",
                    "example": false,
                    "description": "Ignora la caché y vuelve a consultar la fuente oficial. Ojo: una consulta refrescada con datos siempre cobra (el hit de caché no)."
                  }
                }
              },
              "example": {
                "placa": "ABC123",
                "docType": "CC",
                "docNumber": "1020304050",
                "primerApellido": "PÉREZ",
                "ciudad": "Bogotá"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Consulta ejecutada. Cada fuente reporta su propio status (ok, empty, error).",
            "content": {
              "application/json": {
                "example": {
                  "input": {
                    "placa": "ABC123",
                    "docType": "CC",
                    "docNumber": "1020304050"
                  },
                  "mode": "live",
                  "generatedAt": "2026-07-24T15:04:05.000Z",
                  "vehicle": {
                    "source": "vehiculo",
                    "status": "ok",
                    "fetchedAt": "2026-07-24T15:04:05.000Z",
                    "mode": "live",
                    "data": {
                      "placa": "ABC123",
                      "marca": "MAZDA",
                      "linea": "CX-30",
                      "modelo": 2023,
                      "cilindraje": 2000,
                      "combustible": "GASOLINA",
                      "servicio": "Particular",
                      "carroceria": "CAMIONETA",
                      "color": "ROJO",
                      "motor": "MTR0000001",
                      "chasis": "9GAJC6915FB040270",
                      "vin": "9GAJC6915FB040270",
                      "fechaMatricula": "15/03/2023",
                      "organismoTransito": "SECRETARIA DISTRITAL DE MOVILIDAD DE BOGOTA",
                      "estado": "activo",
                      "clase": "CAMIONETA"
                    }
                  },
                  "soat": {
                    "source": "soat",
                    "status": "ok",
                    "fetchedAt": "2026-07-24T15:04:05.000Z",
                    "mode": "live",
                    "data": {
                      "vigente": true,
                      "aseguradora": "SBS SEGUROS",
                      "poliza": "1508006948335000",
                      "fechaExpedicion": "20/09/2025",
                      "fechaVencimiento": "19/09/2026",
                      "diasParaVencer": 69
                    }
                  },
                  "rtm": {
                    "source": "rtm",
                    "status": "ok",
                    "fetchedAt": "2026-07-24T15:04:05.000Z",
                    "mode": "live",
                    "data": {
                      "vigente": true,
                      "exento": false,
                      "fechaPrimeraRevision": null,
                      "cda": "CDA FONTIBON S.A.S",
                      "fechaExpedicion": "22/09/2025",
                      "fechaVencimiento": "22/09/2026",
                      "diasParaVencer": 72,
                      "certificadoNumero": "189733821"
                    }
                  },
                  "antecedentes": {
                    "source": "antecedentes",
                    "status": "ok",
                    "fetchedAt": "2026-07-24T15:04:05.000Z",
                    "mode": "live",
                    "data": {
                      "prendas": [
                        {
                          "acreedor": "RCI COLOMBIA S.A. COMPAÑIA DE FINANCIAMIENTO",
                          "docAcreedor": "900977629",
                          "tipoDocAcreedor": "NIT",
                          "fechaInscripcion": "2021-09-30",
                          "confecamaras": true
                        }
                      ],
                      "embargos": [],
                      "historicoPropietarios": 1
                    }
                  },
                  "simit": {
                    "source": "multas",
                    "status": "ok",
                    "fetchedAt": "2026-07-24T15:04:05.000Z",
                    "mode": "live",
                    "data": {
                      "totalDeuda": 0,
                      "totalMultas": 0,
                      "multas": [],
                      "acuerdosPago": 0
                    }
                  },
                  "impuestos": {
                    "source": "Bogotá D.C.",
                    "status": "info",
                    "fetchedAt": "2026-07-24T15:04:05.000Z",
                    "mode": "live",
                    "data": null,
                    "portalUrl": "https://www.haciendabogota.gov.co/es/sdh/pagos-impuesto-vehiculos",
                    "error": "Tu vehículo está matriculado en Bogotá D.C. Paga tu impuesto en el portal oficial del departamento."
                  },
                  "fasecolda": {
                    "source": "avaluo",
                    "status": "info",
                    "fetchedAt": "2026-07-24T15:04:05.000Z",
                    "mode": "live",
                    "data": {
                      "codigo": "08053096",
                      "marca": "MAZDA",
                      "linea": "CX-30",
                      "modelo": 2023,
                      "valorComercial": 98000000,
                      "rangoMercado": {
                        "min": 92000000,
                        "max": 104000000
                      },
                      "clase": "CAMIONETA"
                    }
                  },
                  "picoYPlaca": {
                    "source": "pico-y-placa",
                    "status": "ok",
                    "fetchedAt": "2026-07-24T15:04:05.000Z",
                    "mode": "live",
                    "ubicacion": {
                      "matched": true,
                      "source": "ciudad",
                      "consulta": {
                        "ciudad": "Bogotá"
                      },
                      "ciudad": "Bogotá",
                      "departamento": "Bogotá D.C."
                    },
                    "data": [
                      {
                        "ciudad": "Bogotá",
                        "departamento": "Bogotá D.C.",
                        "tipoVehiculo": "carro",
                        "digitoPlaca": "ultimo",
                        "tienePicoYPlaca": true,
                        "esquema": "parImpar",
                        "hoyAplica": false,
                        "manianaAplica": true,
                        "digitosHoy": [
                          1,
                          2,
                          3,
                          4,
                          5
                        ],
                        "digitosManiana": [
                          6,
                          7,
                          8,
                          9,
                          0
                        ],
                        "diasSemana": [],
                        "horarios": "L–V, 6:00–21:00",
                        "vigencia": "Vigente en julio de 2026",
                        "fuente": "https://www.movilidadbogota.gov.co/pico-y-placa"
                      }
                    ]
                  },
                  "licencia": {
                    "data": {
                      "documentType": "CC",
                      "documentNumber": "1020304050",
                      "fullName": "J**N P***Z",
                      "driverStatus": "ACTIVO",
                      "citizenStatus": "ACTIVA",
                      "totalLicenses": "1",
                      "licenses": [
                        {
                          "category": "B1",
                          "status": "ACTIVA",
                          "licenceNumber": "1020304050",
                          "otExpide": "INSTITUTO DE MOVILIDAD",
                          "expeditionDate": "23/04/2025",
                          "dueDate": "23/04/2035",
                          "restrictions": null
                        }
                      ],
                      "infractions": {
                        "tieneMultas": "NO",
                        "nroPazYSalvo": "885466652067"
                      }
                    },
                    "mode": "live",
                    "fetchedAt": "2026-07-24T15:04:05.000Z"
                  },
                  "cost": 2
                }
              }
            }
          },
          "400": {
            "description": "Cuerpo inválido: placa o documento con formato incorrecto (code: bad_request)."
          },
          "401": {
            "description": "No autenticado o API key inválida (code: unauthorized)."
          },
          "402": {
            "description": "Sin créditos suficientes (code: no_credits)."
          },
          "404": {
            "description": "La fuente oficial respondió y no hay datos para la consulta. No reintentar: el resultado sería el mismo. code: propietario_no_coincide (el documento no es de un propietario activo del vehículo), vehiculo_no_registrado (el vehículo no tiene información registrada) o consulta_sin_resultado. Cada uno de esos códigos trae 10 consultas sin resultado gratis por mes y cuenta, con cuotas independientes; a partir de la 11 de ese código cobra como una consulta normal. Repetir una que ya salió sin resultado no cobra nunca (se responde de caché con fromCache: true). El body trae charged (si esta consulta cobró) y freeNoResultsLeft (cuántas gratis quedan en el mes para ESE código)."
          },
          "429": {
            "description": "Rate limit excedido: 1000 consultas/minuto por API key (code: rate_limited). Respeta Retry-After."
          },
          "500": {
            "description": "Error interno (code: internal_error)."
          },
          "502": {
            "description": "La fuente oficial no respondió a tiempo (code: source_error). Reintentar más tarde. No se cobra crédito."
          }
        }
      }
    },
    "/consulta": {
      "post": {
        "operationId": "consulta",
        "summary": "Consulta vehicular (RUNT)",
        "description": "Ficha completa del RUNT por placa: informacionGeneral (≈40 campos del vehículo), datosTecnicos, histórico completo de SOAT y de tecnomecánica (todas las vigencias, no solo la última), pólizas de responsabilidad civil, tarjeta de operación, blindaje, solicitudes, garantías mobiliarias, limitaciones a la propiedad y normalización. Es la respuesta más extensa de la API: si solo necesitas marca/línea/modelo usa Vehículo básico. Costo: 1 crédito por consulta con datos.",
        "x-credits": 1,
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "placa",
                  "docType",
                  "docNumber"
                ],
                "properties": {
                  "placa": {
                    "type": "string",
                    "example": "ABC123",
                    "description": "Placa del vehículo. 5 a 7 caracteres alfanuméricos: cubre AAA000, AAA00A y los formatos menos comunes (AAA00, AAAA00). Los guiones y espacios se ignoran."
                  },
                  "docType": {
                    "type": "string",
                    "example": "CC",
                    "description": "Tipo de documento del propietario (CC, CE, NIT, PA, TI, CD, PPT, RC). Se aceptan alias comunes: PAS y PASAPORTE se normalizan a PA, y P.P.T. y P.P. —como lo abrevia la tarjeta de propiedad— se normalizan a PPT.",
                    "enum": [
                      "CC",
                      "CE",
                      "NIT",
                      "PA",
                      "TI",
                      "CD",
                      "PPT",
                      "RC"
                    ]
                  },
                  "docNumber": {
                    "type": "string",
                    "example": "1020304050",
                    "description": "Número de documento del propietario. Alias aceptado: `doc`."
                  },
                  "refresh": {
                    "type": "boolean",
                    "example": false,
                    "description": "Ignora la caché y vuelve a consultar la fuente oficial. Ojo: una consulta refrescada con datos siempre cobra (el hit de caché no)."
                  },
                  "format": {
                    "type": "string",
                    "example": "complete",
                    "description": "`complete` (default) incluye `data.plate`; `vehicle-by-plate` lo omite para dejar el shape RUNT puro."
                  }
                }
              },
              "example": {
                "placa": "ABC123",
                "docType": "CC",
                "docNumber": "1020304050"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Consulta ejecutada. Cada fuente reporta su propio status (ok, empty, error).",
            "content": {
              "application/json": {
                "example": {
                  "data": {
                    "documentNumber": "1020304050",
                    "plate": "ABC123",
                    "vin": "9GAJC6915FB040270",
                    "informacionGeneral": {
                      "capacidadCarga": null,
                      "cilindraje": "2000",
                      "claseVehiculo": "CAMIONETA",
                      "clasificacion": "VEHICULO PARTICULAR",
                      "color": "ROJO",
                      "diasMatriculado": "1227",
                      "esRegrabadoChasis": "NO",
                      "esRegrabadoMotor": "NO",
                      "esRegrabadoSerie": "NO",
                      "esRegrabadoVin": "NO",
                      "estadoDelVehiculo": "ACTIVO",
                      "fechaExpedLTImportacion": "",
                      "fechaMatricula": "15/03/2023",
                      "fechaVenciLTImportacion": "",
                      "idTipoServicio": "1",
                      "linea": "CX-30",
                      "marca": "MAZDA",
                      "modelo": "2023",
                      "mostrarSolicitudes": "NO",
                      "noChasis": "9GAJC6915FB040270",
                      "noEjes": "2",
                      "noIdentificacion": null,
                      "noLicenciaTransito": "12345678",
                      "noMotor": "MTR0000001",
                      "noPlaca": "ABC123",
                      "noSerie": "9GAJC6915FB040270",
                      "noVin": "9GAJC6915FB040270",
                      "nombrePais": null,
                      "organismoTransito": "SECRETARIA DISTRITAL DE MOVILIDAD DE BOGOTA",
                      "pasajerosSentados": "5",
                      "pasajerosTotal": null,
                      "pesoBruto": "1650",
                      "prendas": "NO",
                      "puertas": "5",
                      "repotenciado": "NO",
                      "seguridadEstado": "NO",
                      "subpartida": null,
                      "tarjetaServicio": "NO",
                      "tieneGravamenes": "NO",
                      "tieneLTImportacion": false,
                      "tipoCarroceria": "WAGON",
                      "tipoCombustible": "GASOLINA",
                      "tipoMaquinaria": null,
                      "tipoServicio": "Particular",
                      "validacionDIAN": "Exitoso",
                      "vehiculoEnsenanza": "NO",
                      "verValidaDIAN": true
                    },
                    "datosTecnicos": {
                      "capacidadCarga": null,
                      "pesoBrutoVehicular": null,
                      "noEjes": null,
                      "noLlantas": null,
                      "alto": null,
                      "ancho": null,
                      "largo": null,
                      "pasajerosTotal": null,
                      "pasajerosSentados": null,
                      "rodaje": null,
                      "peso": null
                    },
                    "soat": [
                      {
                        "entidadExpideSoat": "SBS SEGUROS",
                        "estado": "VIGENTE",
                        "estadoSoat": "VIGENTE",
                        "fechaExpediSoat": "20/09/2025",
                        "fechaExpedicion": "20/09/2025",
                        "fechaVencimiento": "19/09/2026",
                        "fechaVigencia": "20/09/2025",
                        "noPoliza": "1508006948335000",
                        "nombrePais": null,
                        "origen": "EXPEDICION",
                        "placa": "ABC123",
                        "tipoTarifa": "TARIFA PLENA"
                      }
                    ],
                    "tecnoMecanica": [
                      {
                        "cdaExpide": "CDA FONTIBON S.A.S",
                        "estado": "APROBADA",
                        "fechaExpedicion": "22/09/2025",
                        "fechaVencimiento": "22/09/2026",
                        "informacionConsistente": "SI",
                        "nroCertificado": "189733821",
                        "numeroPlaca": "ABC123",
                        "tipoRevision": "REVISION PERIODICA",
                        "url": "d4ef5ac5-6c14-4185-b382-98a204ac6fa7",
                        "vigente": "SI"
                      }
                    ],
                    "polizasResponsabilidadCivil": [],
                    "tarjetaOperacion": null,
                    "informacionBlindaje": {
                      "autorizacion": null,
                      "blindado": null,
                      "fechaBlindaje": null,
                      "fechaDesblindaje": null,
                      "fechaExpedicionCertificado": null,
                      "fechaExpedicionCertificadoFormatoWS": null,
                      "idDocumentoCertificadoBlindaje": null,
                      "nivelBlindaje": null,
                      "nivelBlindajeNumero": null,
                      "numeroResolucion": null,
                      "tipoBlindajeNombre": null
                    },
                    "solicitudes": [],
                    "garantiasMobiliarias": [],
                    "garantiasFavorDe": [],
                    "limitacionPropiedad": [],
                    "normalizacionSaneamiento": []
                  },
                  "mode": "live",
                  "fetchedAt": "2026-07-24T15:04:05.000Z"
                }
              }
            }
          },
          "400": {
            "description": "Cuerpo inválido: placa o documento con formato incorrecto (code: bad_request)."
          },
          "401": {
            "description": "No autenticado o API key inválida (code: unauthorized)."
          },
          "402": {
            "description": "Sin créditos suficientes (code: no_credits)."
          },
          "404": {
            "description": "La fuente oficial respondió y no hay datos para la consulta. No reintentar: el resultado sería el mismo. code: propietario_no_coincide (el documento no es de un propietario activo del vehículo), vehiculo_no_registrado (el vehículo no tiene información registrada) o consulta_sin_resultado. Cada uno de esos códigos trae 10 consultas sin resultado gratis por mes y cuenta, con cuotas independientes; a partir de la 11 de ese código cobra como una consulta normal. Repetir una que ya salió sin resultado no cobra nunca (se responde de caché con fromCache: true). El body trae charged (si esta consulta cobró) y freeNoResultsLeft (cuántas gratis quedan en el mes para ESE código)."
          },
          "429": {
            "description": "Rate limit excedido: 1000 consultas/minuto por API key (code: rate_limited). Respeta Retry-After."
          },
          "500": {
            "description": "Error interno (code: internal_error)."
          },
          "502": {
            "description": "La fuente oficial no respondió a tiempo (code: source_error). Reintentar más tarde. No se cobra crédito."
          }
        }
      }
    },
    "/consulta-por-vin": {
      "post": {
        "operationId": "consulta-por-vin",
        "summary": "Consulta vehicular por VIN",
        "description": "La MISMA ficha del RUNT que `/api/consulta` —informacionGeneral, datosTecnicos, histórico completo de SOAT y tecnomecánica, pólizas, solicitudes, garantías, limitaciones y normalización— pero entrando por VIN en vez de placa, y **sin documento del propietario**. Úsalo cuando tengas el VIN (o el número de chasis) pero no la cédula del dueño: la consulta por placa exige que el documento sea el del propietario ACTIVO y falla si no coincide. La respuesta trae la placa en `data.plate`, así que también sirve de puente VIN → placa. Único campo que cambia frente a `/api/consulta`: `data.documentNumber` viene vacío, porque no se pidió. Costo: 1 crédito por consulta con datos.",
        "x-credits": 1,
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "vin"
                ],
                "properties": {
                  "vin": {
                    "type": "string",
                    "example": "9GAJC6915FB040270",
                    "description": "VIN del vehículo (11–17 caracteres, sin I, O ni Q). Alias aceptado: `chasis` — en la mayoría de vehículos el RUNT registra el mismo valor en VIN y número de chasis."
                  },
                  "refresh": {
                    "type": "boolean",
                    "example": false,
                    "description": "Ignora la caché y vuelve a consultar la fuente oficial. Ojo: una consulta refrescada con datos siempre cobra (el hit de caché no)."
                  }
                }
              },
              "example": {
                "vin": "9GAJC6915FB040270"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Consulta ejecutada. Cada fuente reporta su propio status (ok, empty, error).",
            "content": {
              "application/json": {
                "example": {
                  "data": {
                    "documentNumber": "",
                    "plate": "ABC123",
                    "vin": "9GAJC6915FB040270",
                    "informacionGeneral": {
                      "capacidadCarga": null,
                      "cilindraje": "2000",
                      "claseVehiculo": "CAMIONETA",
                      "clasificacion": "VEHICULO PARTICULAR",
                      "color": "ROJO",
                      "diasMatriculado": "1227",
                      "esRegrabadoChasis": "NO",
                      "esRegrabadoMotor": "NO",
                      "esRegrabadoSerie": "NO",
                      "esRegrabadoVin": "NO",
                      "estadoDelVehiculo": "ACTIVO",
                      "fechaExpedLTImportacion": "",
                      "fechaMatricula": "15/03/2023",
                      "fechaVenciLTImportacion": "",
                      "idTipoServicio": "1",
                      "linea": "CX-30",
                      "marca": "MAZDA",
                      "modelo": "2023",
                      "mostrarSolicitudes": "NO",
                      "noChasis": "9GAJC6915FB040270",
                      "noEjes": "2",
                      "noIdentificacion": null,
                      "noLicenciaTransito": "12345678",
                      "noMotor": "MTR0000001",
                      "noPlaca": "ABC123",
                      "noSerie": "9GAJC6915FB040270",
                      "noVin": "9GAJC6915FB040270",
                      "nombrePais": null,
                      "organismoTransito": "SECRETARIA DISTRITAL DE MOVILIDAD DE BOGOTA",
                      "pasajerosSentados": "5",
                      "pasajerosTotal": null,
                      "pesoBruto": "1650",
                      "prendas": "NO",
                      "puertas": "5",
                      "repotenciado": "NO",
                      "seguridadEstado": "NO",
                      "subpartida": null,
                      "tarjetaServicio": "NO",
                      "tieneGravamenes": "NO",
                      "tieneLTImportacion": false,
                      "tipoCarroceria": "WAGON",
                      "tipoCombustible": "GASOLINA",
                      "tipoMaquinaria": null,
                      "tipoServicio": "Particular",
                      "validacionDIAN": "Exitoso",
                      "vehiculoEnsenanza": "NO",
                      "verValidaDIAN": true
                    },
                    "datosTecnicos": {
                      "capacidadCarga": null,
                      "pesoBrutoVehicular": null,
                      "noEjes": null,
                      "noLlantas": null,
                      "alto": null,
                      "ancho": null,
                      "largo": null,
                      "pasajerosTotal": null,
                      "pasajerosSentados": null,
                      "rodaje": null,
                      "peso": null
                    },
                    "soat": [
                      {
                        "entidadExpideSoat": "SBS SEGUROS",
                        "estado": "VIGENTE",
                        "estadoSoat": "VIGENTE",
                        "fechaExpediSoat": "20/09/2025",
                        "fechaExpedicion": "20/09/2025",
                        "fechaVencimiento": "19/09/2026",
                        "fechaVigencia": "20/09/2025",
                        "noPoliza": "1508006948335000",
                        "nombrePais": null,
                        "origen": "EXPEDICION",
                        "placa": "ABC123",
                        "tipoTarifa": "TARIFA PLENA"
                      }
                    ],
                    "tecnoMecanica": [
                      {
                        "cdaExpide": "CDA FONTIBON S.A.S",
                        "estado": "APROBADA",
                        "fechaExpedicion": "22/09/2025",
                        "fechaVencimiento": "22/09/2026",
                        "informacionConsistente": "SI",
                        "nroCertificado": "189733821",
                        "numeroPlaca": "ABC123",
                        "tipoRevision": "REVISION PERIODICA",
                        "url": "d4ef5ac5-6c14-4185-b382-98a204ac6fa7",
                        "vigente": "SI"
                      }
                    ],
                    "polizasResponsabilidadCivil": [],
                    "tarjetaOperacion": null,
                    "informacionBlindaje": {
                      "autorizacion": null,
                      "blindado": null,
                      "fechaBlindaje": null,
                      "fechaDesblindaje": null,
                      "fechaExpedicionCertificado": null,
                      "fechaExpedicionCertificadoFormatoWS": null,
                      "idDocumentoCertificadoBlindaje": null,
                      "nivelBlindaje": null,
                      "nivelBlindajeNumero": null,
                      "numeroResolucion": null,
                      "tipoBlindajeNombre": null
                    },
                    "solicitudes": [],
                    "garantiasMobiliarias": [],
                    "garantiasFavorDe": [],
                    "limitacionPropiedad": [],
                    "normalizacionSaneamiento": []
                  },
                  "mode": "live",
                  "fetchedAt": "2026-07-24T15:04:05.000Z"
                }
              }
            }
          },
          "400": {
            "description": "Cuerpo inválido: placa o documento con formato incorrecto (code: bad_request)."
          },
          "401": {
            "description": "No autenticado o API key inválida (code: unauthorized)."
          },
          "402": {
            "description": "Sin créditos suficientes (code: no_credits)."
          },
          "404": {
            "description": "La fuente oficial respondió y no hay datos para la consulta. No reintentar: el resultado sería el mismo. code: propietario_no_coincide (el documento no es de un propietario activo del vehículo), vehiculo_no_registrado (el vehículo no tiene información registrada) o consulta_sin_resultado. Cada uno de esos códigos trae 10 consultas sin resultado gratis por mes y cuenta, con cuotas independientes; a partir de la 11 de ese código cobra como una consulta normal. Repetir una que ya salió sin resultado no cobra nunca (se responde de caché con fromCache: true). El body trae charged (si esta consulta cobró) y freeNoResultsLeft (cuántas gratis quedan en el mes para ESE código)."
          },
          "429": {
            "description": "Rate limit excedido: 1000 consultas/minuto por API key (code: rate_limited). Respeta Retry-After."
          },
          "500": {
            "description": "Error interno (code: internal_error)."
          },
          "502": {
            "description": "La fuente oficial no respondió a tiempo (code: source_error). Reintentar más tarde. No se cobra crédito."
          }
        }
      }
    },
    "/apto-traspaso": {
      "post": {
        "operationId": "apto-traspaso",
        "summary": "Apto para traspaso",
        "description": "Semáforo SÍ/NO de si un vehículo está apto para traspaso, derivado del RUNT: sin gravámenes, prendas, limitaciones a la propiedad ni garantías, y con el registro activo. Devuelve el flag y la lista de bloqueos concretos en texto listo para mostrar. `status` es ok si está apto, danger si el bloqueo es un gravamen/prenda/limitación y warn si solo el estado no es ACTIVO. Costo: 1 crédito por consulta con datos.",
        "x-credits": 1,
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "placa",
                  "docType",
                  "docNumber"
                ],
                "properties": {
                  "placa": {
                    "type": "string",
                    "example": "ABC123",
                    "description": "Placa del vehículo. 5 a 7 caracteres alfanuméricos: cubre AAA000, AAA00A y los formatos menos comunes (AAA00, AAAA00). Los guiones y espacios se ignoran."
                  },
                  "docType": {
                    "type": "string",
                    "example": "CC",
                    "description": "Tipo de documento del propietario (CC, CE, NIT, PA, TI, CD, PPT, RC). Se aceptan alias comunes: PAS y PASAPORTE se normalizan a PA, y P.P.T. y P.P. —como lo abrevia la tarjeta de propiedad— se normalizan a PPT.",
                    "enum": [
                      "CC",
                      "CE",
                      "NIT",
                      "PA",
                      "TI",
                      "CD",
                      "PPT",
                      "RC"
                    ]
                  },
                  "docNumber": {
                    "type": "string",
                    "example": "1020304050",
                    "description": "Número de documento del propietario. Alias aceptado: `doc`."
                  },
                  "refresh": {
                    "type": "boolean",
                    "example": false,
                    "description": "Ignora la caché y vuelve a consultar la fuente oficial. Ojo: una consulta refrescada con datos siempre cobra (el hit de caché no)."
                  }
                }
              },
              "example": {
                "placa": "ABC123",
                "docType": "CC",
                "docNumber": "1020304050"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Consulta ejecutada. Cada fuente reporta su propio status (ok, empty, error).",
            "content": {
              "application/json": {
                "example": {
                  "source": "vehiculo",
                  "status": "ok",
                  "data": {
                    "placa": "ABC123",
                    "aptoTraspaso": true,
                    "estado": "ACTIVO",
                    "bloqueos": [],
                    "detalle": {
                      "tieneGravamenes": false,
                      "tienePrendas": false,
                      "limitaciones": 0,
                      "garantias": 0,
                      "estadoDelVehiculo": "ACTIVO"
                    }
                  },
                  "mode": "live",
                  "fetchedAt": "2026-07-24T15:04:05.000Z"
                }
              }
            }
          },
          "400": {
            "description": "Cuerpo inválido: placa o documento con formato incorrecto (code: bad_request)."
          },
          "401": {
            "description": "No autenticado o API key inválida (code: unauthorized)."
          },
          "402": {
            "description": "Sin créditos suficientes (code: no_credits)."
          },
          "404": {
            "description": "La fuente oficial respondió y no hay datos para la consulta. No reintentar: el resultado sería el mismo. code: propietario_no_coincide (el documento no es de un propietario activo del vehículo), vehiculo_no_registrado (el vehículo no tiene información registrada) o consulta_sin_resultado. Cada uno de esos códigos trae 10 consultas sin resultado gratis por mes y cuenta, con cuotas independientes; a partir de la 11 de ese código cobra como una consulta normal. Repetir una que ya salió sin resultado no cobra nunca (se responde de caché con fromCache: true). El body trae charged (si esta consulta cobró) y freeNoResultsLeft (cuántas gratis quedan en el mes para ESE código)."
          },
          "429": {
            "description": "Rate limit excedido: 1000 consultas/minuto por API key (code: rate_limited). Respeta Retry-After."
          },
          "500": {
            "description": "Error interno (code: internal_error)."
          },
          "502": {
            "description": "La fuente oficial no respondió a tiempo (code: source_error). Reintentar más tarde. No se cobra crédito."
          }
        }
      }
    },
    "/vehiculo-basico": {
      "post": {
        "operationId": "vehiculo-basico",
        "summary": "Vehículo básico (liviano)",
        "description": "Proyección liviana de la ficha del RUNT por placa: exactamente 12 campos — placa, marca, línea, modelo, cilindraje, color, clase, servicio, combustible, estado, fecha de matrícula y organismo de tránsito. Todos texto (`fechaMatricula` puede venir null). Respuesta mínima para apps que solo necesitan lo esencial; `status` siempre es info porque describe el vehículo sin calificarlo. Costo: 1 crédito por consulta con datos.",
        "x-credits": 1,
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "placa",
                  "docType",
                  "docNumber"
                ],
                "properties": {
                  "placa": {
                    "type": "string",
                    "example": "ABC123",
                    "description": "Placa del vehículo. 5 a 7 caracteres alfanuméricos: cubre AAA000, AAA00A y los formatos menos comunes (AAA00, AAAA00). Los guiones y espacios se ignoran."
                  },
                  "docType": {
                    "type": "string",
                    "example": "CC",
                    "description": "Tipo de documento del propietario (CC, CE, NIT, PA, TI, CD, PPT, RC). Se aceptan alias comunes: PAS y PASAPORTE se normalizan a PA, y P.P.T. y P.P. —como lo abrevia la tarjeta de propiedad— se normalizan a PPT.",
                    "enum": [
                      "CC",
                      "CE",
                      "NIT",
                      "PA",
                      "TI",
                      "CD",
                      "PPT",
                      "RC"
                    ]
                  },
                  "docNumber": {
                    "type": "string",
                    "example": "1020304050",
                    "description": "Número de documento del propietario. Alias aceptado: `doc`."
                  },
                  "refresh": {
                    "type": "boolean",
                    "example": false,
                    "description": "Ignora la caché y vuelve a consultar la fuente oficial. Ojo: una consulta refrescada con datos siempre cobra (el hit de caché no)."
                  }
                }
              },
              "example": {
                "placa": "ABC123",
                "docType": "CC",
                "docNumber": "1020304050"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Consulta ejecutada. Cada fuente reporta su propio status (ok, empty, error).",
            "content": {
              "application/json": {
                "example": {
                  "source": "vehiculo",
                  "status": "info",
                  "data": {
                    "placa": "ABC123",
                    "marca": "MAZDA",
                    "linea": "CX-30",
                    "modelo": "2023",
                    "cilindraje": "2000",
                    "color": "ROJO",
                    "clase": "CAMIONETA",
                    "servicio": "Particular",
                    "combustible": "GASOLINA",
                    "estado": "ACTIVO",
                    "fechaMatricula": "15/03/2023",
                    "organismoTransito": "SECRETARIA DISTRITAL DE MOVILIDAD DE BOGOTA"
                  },
                  "mode": "live",
                  "fetchedAt": "2026-07-24T15:04:05.000Z"
                }
              }
            }
          },
          "400": {
            "description": "Cuerpo inválido: placa o documento con formato incorrecto (code: bad_request)."
          },
          "401": {
            "description": "No autenticado o API key inválida (code: unauthorized)."
          },
          "402": {
            "description": "Sin créditos suficientes (code: no_credits)."
          },
          "404": {
            "description": "La fuente oficial respondió y no hay datos para la consulta. No reintentar: el resultado sería el mismo. code: propietario_no_coincide (el documento no es de un propietario activo del vehículo), vehiculo_no_registrado (el vehículo no tiene información registrada) o consulta_sin_resultado. Cada uno de esos códigos trae 10 consultas sin resultado gratis por mes y cuenta, con cuotas independientes; a partir de la 11 de ese código cobra como una consulta normal. Repetir una que ya salió sin resultado no cobra nunca (se responde de caché con fromCache: true). El body trae charged (si esta consulta cobró) y freeNoResultsLeft (cuántas gratis quedan en el mes para ESE código)."
          },
          "429": {
            "description": "Rate limit excedido: 1000 consultas/minuto por API key (code: rate_limited). Respeta Retry-After."
          },
          "500": {
            "description": "Error interno (code: internal_error)."
          },
          "502": {
            "description": "La fuente oficial no respondió a tiempo (code: source_error). Reintentar más tarde. No se cobra crédito."
          }
        }
      }
    },
    "/multas": {
      "post": {
        "operationId": "multas",
        "summary": "Multas SIMIT",
        "description": "Comparendos y deuda del SIMIT consolidados por placa + documento: total adeudado en pesos, número de multas, el detalle de cada una (fecha, organismo, infracción, código, estado pendiente/acuerdo/pagada y valor) y cuántos acuerdos de pago hay. `status`: ok sin multas, warn con multas y danger si la deuda pasa de $1.000.000. Costo: 1 crédito por consulta con datos.",
        "x-credits": 1,
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "placa",
                  "docType",
                  "docNumber"
                ],
                "properties": {
                  "placa": {
                    "type": "string",
                    "example": "ABC123",
                    "description": "Placa del vehículo. 5 a 7 caracteres alfanuméricos: cubre AAA000, AAA00A y los formatos menos comunes (AAA00, AAAA00). Los guiones y espacios se ignoran."
                  },
                  "docType": {
                    "type": "string",
                    "example": "CC",
                    "description": "Tipo de documento del propietario (CC, CE, NIT, PA, TI, CD, PPT, RC). Se aceptan alias comunes: PAS y PASAPORTE se normalizan a PA, y P.P.T. y P.P. —como lo abrevia la tarjeta de propiedad— se normalizan a PPT.",
                    "enum": [
                      "CC",
                      "CE",
                      "NIT",
                      "PA",
                      "TI",
                      "CD",
                      "PPT",
                      "RC"
                    ]
                  },
                  "docNumber": {
                    "type": "string",
                    "example": "1020304050",
                    "description": "Número de documento del propietario. Alias aceptado: `doc`."
                  },
                  "refresh": {
                    "type": "boolean",
                    "example": false,
                    "description": "Ignora la caché y vuelve a consultar la fuente oficial. Ojo: una consulta refrescada con datos siempre cobra (el hit de caché no)."
                  }
                }
              },
              "example": {
                "placa": "ABC123",
                "docType": "CC",
                "docNumber": "1020304050"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Consulta ejecutada. Cada fuente reporta su propio status (ok, empty, error).",
            "content": {
              "application/json": {
                "example": {
                  "source": "multas",
                  "status": "warn",
                  "data": {
                    "totalDeuda": 522700,
                    "totalMultas": 1,
                    "multas": [
                      {
                        "comparendoId": "11001000000012345678",
                        "fecha": "2025-03-15",
                        "organismo": "SECRETARÍA DISTRITAL DE MOVILIDAD DE BOGOTÁ",
                        "infraccion": "No respetar pico y placa",
                        "codigo": "C14",
                        "estado": "pendiente",
                        "valor": 522700
                      }
                    ],
                    "acuerdosPago": 0
                  },
                  "mode": "live",
                  "fetchedAt": "2026-07-24T15:04:05.000Z"
                }
              }
            }
          },
          "400": {
            "description": "Cuerpo inválido: placa o documento con formato incorrecto (code: bad_request)."
          },
          "401": {
            "description": "No autenticado o API key inválida (code: unauthorized)."
          },
          "402": {
            "description": "Sin créditos suficientes (code: no_credits)."
          },
          "404": {
            "description": "La fuente oficial respondió y no hay datos para la consulta. No reintentar: el resultado sería el mismo. code: propietario_no_coincide (el documento no es de un propietario activo del vehículo), vehiculo_no_registrado (el vehículo no tiene información registrada) o consulta_sin_resultado. Cada uno de esos códigos trae 10 consultas sin resultado gratis por mes y cuenta, con cuotas independientes; a partir de la 11 de ese código cobra como una consulta normal. Repetir una que ya salió sin resultado no cobra nunca (se responde de caché con fromCache: true). El body trae charged (si esta consulta cobró) y freeNoResultsLeft (cuántas gratis quedan en el mes para ESE código)."
          },
          "429": {
            "description": "Rate limit excedido: 1000 consultas/minuto por API key (code: rate_limited). Respeta Retry-After."
          },
          "500": {
            "description": "Error interno (code: internal_error)."
          },
          "502": {
            "description": "La fuente oficial no respondió a tiempo (code: source_error). Reintentar más tarde. No se cobra crédito."
          }
        }
      }
    },
    "/comparendos": {
      "post": {
        "operationId": "comparendos",
        "summary": "Comparendos por cédula",
        "description": "Comparendos de una persona por cédula (fuente SIMIT): lista tipada con fecha, organismo, infracción, código, estado, valor y departamento de cada comparendo, más el total adeudado. A diferencia de Multas SIMIT (que consolida por placa), este devuelve los comparendos de la persona. `status`: ok sin comparendos, warn con comparendos y danger si la deuda pasa de $1.000.000. Costo: 1 crédito por consulta con datos.",
        "x-credits": 1,
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "docType",
                  "docNumber"
                ],
                "properties": {
                  "docType": {
                    "type": "string",
                    "example": "CC",
                    "description": "Tipo de documento (CC, CE, NIT, PA, TI, CD, PPT, RC). Se aceptan alias comunes: PAS y PASAPORTE se normalizan a PA, y P.P.T. y P.P. se normalizan a PPT.",
                    "enum": [
                      "CC",
                      "CE",
                      "NIT",
                      "PA",
                      "TI",
                      "CD",
                      "PPT",
                      "RC"
                    ]
                  },
                  "docNumber": {
                    "type": "string",
                    "example": "1020304050",
                    "description": "Número de documento. Alias aceptado: `doc`."
                  },
                  "refresh": {
                    "type": "boolean",
                    "example": false,
                    "description": "Ignora la caché y vuelve a consultar la fuente oficial. Ojo: una consulta refrescada con datos siempre cobra (el hit de caché no)."
                  }
                }
              },
              "example": {
                "docType": "CC",
                "docNumber": "1020304050"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Consulta ejecutada. Cada fuente reporta su propio status (ok, empty, error).",
            "content": {
              "application/json": {
                "example": {
                  "source": "multas",
                  "status": "warn",
                  "data": {
                    "documentNumber": "1020304050",
                    "totalComparendos": 1,
                    "totalDeuda": 522700,
                    "comparendos": [
                      {
                        "comparendoId": "11001000000012345678",
                        "fecha": "2025-03-15",
                        "organismo": "SECRETARÍA DISTRITAL DE MOVILIDAD DE BOGOTÁ",
                        "infraccion": "No respetar pico y placa",
                        "codigo": "C14",
                        "estado": "pendiente",
                        "valor": 522700,
                        "departamento": "BOGOTÁ D.C."
                      }
                    ]
                  },
                  "mode": "live",
                  "fetchedAt": "2026-07-24T15:04:05.000Z"
                }
              }
            }
          },
          "400": {
            "description": "Cuerpo inválido: placa o documento con formato incorrecto (code: bad_request)."
          },
          "401": {
            "description": "No autenticado o API key inválida (code: unauthorized)."
          },
          "402": {
            "description": "Sin créditos suficientes (code: no_credits)."
          },
          "404": {
            "description": "La fuente oficial respondió y no hay datos para la consulta. No reintentar: el resultado sería el mismo. code: propietario_no_coincide (el documento no es de un propietario activo del vehículo), vehiculo_no_registrado (el vehículo no tiene información registrada) o consulta_sin_resultado. Cada uno de esos códigos trae 10 consultas sin resultado gratis por mes y cuenta, con cuotas independientes; a partir de la 11 de ese código cobra como una consulta normal. Repetir una que ya salió sin resultado no cobra nunca (se responde de caché con fromCache: true). El body trae charged (si esta consulta cobró) y freeNoResultsLeft (cuántas gratis quedan en el mes para ESE código)."
          },
          "429": {
            "description": "Rate limit excedido: 1000 consultas/minuto por API key (code: rate_limited). Respeta Retry-After."
          },
          "500": {
            "description": "Error interno (code: internal_error)."
          },
          "502": {
            "description": "La fuente oficial no respondió a tiempo (code: source_error). Reintentar más tarde. No se cobra crédito."
          }
        }
      }
    },
    "/comparendo": {
      "post": {
        "operationId": "comparendo",
        "summary": "Detalle de comparendo",
        "description": "Detalle de un comparendo puntual: se busca por su número dentro de los comparendos de la persona (cédula) y se devuelve el item completo (fecha, organismo, infracción, código, estado, valor, departamento) o `encontrado: false` con `comparendo: null` si no figura. Ese caso también cobra: la consulta al SIMIT se hizo y la respuesta —que no aparece— es información. `status`: info si no se encontró, ok si está pagada, warn si no. Costo: 1 crédito por consulta con datos.",
        "x-credits": 1,
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "docType",
                  "docNumber",
                  "numeroComparendo"
                ],
                "properties": {
                  "docType": {
                    "type": "string",
                    "example": "CC",
                    "description": "Tipo de documento (CC, CE, NIT, PA, TI, CD, PPT, RC). Se aceptan alias comunes: PAS y PASAPORTE se normalizan a PA, y P.P.T. y P.P. se normalizan a PPT.",
                    "enum": [
                      "CC",
                      "CE",
                      "NIT",
                      "PA",
                      "TI",
                      "CD",
                      "PPT",
                      "RC"
                    ]
                  },
                  "docNumber": {
                    "type": "string",
                    "example": "1020304050",
                    "description": "Número de documento. Alias aceptado: `doc`."
                  },
                  "refresh": {
                    "type": "boolean",
                    "example": false,
                    "description": "Ignora la caché y vuelve a consultar la fuente oficial. Ojo: una consulta refrescada con datos siempre cobra (el hit de caché no)."
                  },
                  "numeroComparendo": {
                    "type": "string",
                    "example": "11001000000012345678",
                    "description": "Número del comparendo a buscar dentro de los de la persona. Alias aceptado: `comparendo`."
                  }
                }
              },
              "example": {
                "docType": "CC",
                "docNumber": "1020304050",
                "numeroComparendo": "11001000000012345678"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Consulta ejecutada. Cada fuente reporta su propio status (ok, empty, error).",
            "content": {
              "application/json": {
                "example": {
                  "source": "multas",
                  "status": "warn",
                  "data": {
                    "documentNumber": "1020304050",
                    "numeroComparendo": "11001000000012345678",
                    "encontrado": true,
                    "comparendo": {
                      "comparendoId": "11001000000012345678",
                      "fecha": "2025-03-15",
                      "organismo": "SECRETARÍA DISTRITAL DE MOVILIDAD DE BOGOTÁ",
                      "infraccion": "No respetar pico y placa",
                      "codigo": "C14",
                      "estado": "pendiente",
                      "valor": 522700,
                      "departamento": "BOGOTÁ D.C."
                    }
                  },
                  "mode": "live",
                  "fetchedAt": "2026-07-24T15:04:05.000Z"
                }
              }
            }
          },
          "400": {
            "description": "Cuerpo inválido: placa o documento con formato incorrecto (code: bad_request)."
          },
          "401": {
            "description": "No autenticado o API key inválida (code: unauthorized)."
          },
          "402": {
            "description": "Sin créditos suficientes (code: no_credits)."
          },
          "404": {
            "description": "La fuente oficial respondió y no hay datos para la consulta. No reintentar: el resultado sería el mismo. code: propietario_no_coincide (el documento no es de un propietario activo del vehículo), vehiculo_no_registrado (el vehículo no tiene información registrada) o consulta_sin_resultado. Cada uno de esos códigos trae 10 consultas sin resultado gratis por mes y cuenta, con cuotas independientes; a partir de la 11 de ese código cobra como una consulta normal. Repetir una que ya salió sin resultado no cobra nunca (se responde de caché con fromCache: true). El body trae charged (si esta consulta cobró) y freeNoResultsLeft (cuántas gratis quedan en el mes para ESE código)."
          },
          "429": {
            "description": "Rate limit excedido: 1000 consultas/minuto por API key (code: rate_limited). Respeta Retry-After."
          },
          "500": {
            "description": "Error interno (code: internal_error)."
          },
          "502": {
            "description": "La fuente oficial no respondió a tiempo (code: source_error). Reintentar más tarde. No se cobra crédito."
          }
        }
      }
    },
    "/acuerdos-pago": {
      "post": {
        "operationId": "acuerdos-pago",
        "summary": "Acuerdos de pago",
        "description": "Acuerdos de pago de comparendos de una persona por cédula (fuente SIMIT): resolución, fecha, estado, valor del acuerdo, saldo pendiente, secretaría y departamento de cada uno, más el total pendiente. `status`: ok sin acuerdos, warn con al menos uno. Costo: 1 crédito por consulta con datos.",
        "x-credits": 1,
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "docType",
                  "docNumber"
                ],
                "properties": {
                  "docType": {
                    "type": "string",
                    "example": "CC",
                    "description": "Tipo de documento (CC, CE, NIT, PA, TI, CD, PPT, RC). Se aceptan alias comunes: PAS y PASAPORTE se normalizan a PA, y P.P.T. y P.P. se normalizan a PPT.",
                    "enum": [
                      "CC",
                      "CE",
                      "NIT",
                      "PA",
                      "TI",
                      "CD",
                      "PPT",
                      "RC"
                    ]
                  },
                  "docNumber": {
                    "type": "string",
                    "example": "1020304050",
                    "description": "Número de documento. Alias aceptado: `doc`."
                  },
                  "refresh": {
                    "type": "boolean",
                    "example": false,
                    "description": "Ignora la caché y vuelve a consultar la fuente oficial. Ojo: una consulta refrescada con datos siempre cobra (el hit de caché no)."
                  }
                }
              },
              "example": {
                "docType": "CC",
                "docNumber": "1020304050"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Consulta ejecutada. Cada fuente reporta su propio status (ok, empty, error).",
            "content": {
              "application/json": {
                "example": {
                  "source": "multas",
                  "status": "warn",
                  "data": {
                    "documentNumber": "1020304050",
                    "totalAcuerdos": 1,
                    "totalPendiente": 500000,
                    "acuerdos": [
                      {
                        "resolucion": "324",
                        "fechaResolucion": "2018-02-16",
                        "estado": "Acuerdo de pago",
                        "valorAcuerdo": 837716,
                        "pendiente": 500000,
                        "secretaria": "Jamundí",
                        "departamento": "Valle del Cauca"
                      }
                    ]
                  },
                  "mode": "live",
                  "fetchedAt": "2026-07-24T15:04:05.000Z"
                }
              }
            }
          },
          "400": {
            "description": "Cuerpo inválido: placa o documento con formato incorrecto (code: bad_request)."
          },
          "401": {
            "description": "No autenticado o API key inválida (code: unauthorized)."
          },
          "402": {
            "description": "Sin créditos suficientes (code: no_credits)."
          },
          "404": {
            "description": "La fuente oficial respondió y no hay datos para la consulta. No reintentar: el resultado sería el mismo. code: propietario_no_coincide (el documento no es de un propietario activo del vehículo), vehiculo_no_registrado (el vehículo no tiene información registrada) o consulta_sin_resultado. Cada uno de esos códigos trae 10 consultas sin resultado gratis por mes y cuenta, con cuotas independientes; a partir de la 11 de ese código cobra como una consulta normal. Repetir una que ya salió sin resultado no cobra nunca (se responde de caché con fromCache: true). El body trae charged (si esta consulta cobró) y freeNoResultsLeft (cuántas gratis quedan en el mes para ESE código)."
          },
          "429": {
            "description": "Rate limit excedido: 1000 consultas/minuto por API key (code: rate_limited). Respeta Retry-After."
          },
          "500": {
            "description": "Error interno (code: internal_error)."
          },
          "502": {
            "description": "La fuente oficial no respondió a tiempo (code: source_error). Reintentar más tarde. No se cobra crédito."
          }
        }
      }
    },
    "/resoluciones": {
      "post": {
        "operationId": "resoluciones",
        "summary": "Resoluciones de tránsito",
        "description": "Resoluciones sancionatorias asociadas a una persona por cédula (fuente SIMIT): las multas que ya tienen número de resolución, con fecha, organismo, infracción, código, estado, valor y departamento, más el total adeudado. `status`: ok sin resoluciones, warn con al menos una y danger si el total pasa de $1.000.000. Costo: 1 crédito por consulta con datos.",
        "x-credits": 1,
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "docType",
                  "docNumber"
                ],
                "properties": {
                  "docType": {
                    "type": "string",
                    "example": "CC",
                    "description": "Tipo de documento (CC, CE, NIT, PA, TI, CD, PPT, RC). Se aceptan alias comunes: PAS y PASAPORTE se normalizan a PA, y P.P.T. y P.P. se normalizan a PPT.",
                    "enum": [
                      "CC",
                      "CE",
                      "NIT",
                      "PA",
                      "TI",
                      "CD",
                      "PPT",
                      "RC"
                    ]
                  },
                  "docNumber": {
                    "type": "string",
                    "example": "1020304050",
                    "description": "Número de documento. Alias aceptado: `doc`."
                  },
                  "refresh": {
                    "type": "boolean",
                    "example": false,
                    "description": "Ignora la caché y vuelve a consultar la fuente oficial. Ojo: una consulta refrescada con datos siempre cobra (el hit de caché no)."
                  }
                }
              },
              "example": {
                "docType": "CC",
                "docNumber": "1020304050"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Consulta ejecutada. Cada fuente reporta su propio status (ok, empty, error).",
            "content": {
              "application/json": {
                "example": {
                  "source": "multas",
                  "status": "warn",
                  "data": {
                    "documentNumber": "1020304050",
                    "totalResoluciones": 1,
                    "totalDeuda": 837716,
                    "resoluciones": [
                      {
                        "comparendoId": "324",
                        "fecha": "2018-02-16",
                        "organismo": "SECRETARÍA DE TRÁNSITO DE JAMUNDÍ",
                        "infraccion": "No pagar comparendo en término",
                        "codigo": "B01",
                        "estado": "acuerdo",
                        "valor": 837716,
                        "departamento": "Valle del Cauca"
                      }
                    ]
                  },
                  "mode": "live",
                  "fetchedAt": "2026-07-24T15:04:05.000Z"
                }
              }
            }
          },
          "400": {
            "description": "Cuerpo inválido: placa o documento con formato incorrecto (code: bad_request)."
          },
          "401": {
            "description": "No autenticado o API key inválida (code: unauthorized)."
          },
          "402": {
            "description": "Sin créditos suficientes (code: no_credits)."
          },
          "404": {
            "description": "La fuente oficial respondió y no hay datos para la consulta. No reintentar: el resultado sería el mismo. code: propietario_no_coincide (el documento no es de un propietario activo del vehículo), vehiculo_no_registrado (el vehículo no tiene información registrada) o consulta_sin_resultado. Cada uno de esos códigos trae 10 consultas sin resultado gratis por mes y cuenta, con cuotas independientes; a partir de la 11 de ese código cobra como una consulta normal. Repetir una que ya salió sin resultado no cobra nunca (se responde de caché con fromCache: true). El body trae charged (si esta consulta cobró) y freeNoResultsLeft (cuántas gratis quedan en el mes para ESE código)."
          },
          "429": {
            "description": "Rate limit excedido: 1000 consultas/minuto por API key (code: rate_limited). Respeta Retry-After."
          },
          "500": {
            "description": "Error interno (code: internal_error)."
          },
          "502": {
            "description": "La fuente oficial no respondió a tiempo (code: source_error). Reintentar más tarde. No se cobra crédito."
          }
        }
      }
    },
    "/suspension-licencia": {
      "post": {
        "operationId": "suspension-licencia",
        "summary": "Suspensión de licencia",
        "description": "Estado de suspensión o cancelación de la licencia de conducción de una persona por cédula (fuente SIMIT): banderas `suspendida`/`cancelada` y, cuando aplica, la vigencia de la medida (fecha desde, fecha hasta y organismo de tránsito); sin medida los tres campos vienen null. `status` es danger si está suspendida o cancelada, ok si no. Crítico para agencias de licencias. Costo: 1 crédito por consulta con datos.",
        "x-credits": 1,
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "docType",
                  "docNumber"
                ],
                "properties": {
                  "docType": {
                    "type": "string",
                    "example": "CC",
                    "description": "Tipo de documento (CC, CE, NIT, PA, TI, CD, PPT, RC). Se aceptan alias comunes: PAS y PASAPORTE se normalizan a PA, y P.P.T. y P.P. se normalizan a PPT.",
                    "enum": [
                      "CC",
                      "CE",
                      "NIT",
                      "PA",
                      "TI",
                      "CD",
                      "PPT",
                      "RC"
                    ]
                  },
                  "docNumber": {
                    "type": "string",
                    "example": "1020304050",
                    "description": "Número de documento. Alias aceptado: `doc`."
                  },
                  "refresh": {
                    "type": "boolean",
                    "example": false,
                    "description": "Ignora la caché y vuelve a consultar la fuente oficial. Ojo: una consulta refrescada con datos siempre cobra (el hit de caché no)."
                  }
                }
              },
              "example": {
                "docType": "CC",
                "docNumber": "1020304050"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Consulta ejecutada. Cada fuente reporta su propio status (ok, empty, error).",
            "content": {
              "application/json": {
                "example": {
                  "source": "multas",
                  "status": "ok",
                  "data": {
                    "documentNumber": "1020304050",
                    "suspendida": false,
                    "cancelada": false,
                    "fechaDesde": null,
                    "fechaHasta": null,
                    "organismo": null
                  },
                  "mode": "live",
                  "fetchedAt": "2026-07-24T15:04:05.000Z"
                }
              }
            }
          },
          "400": {
            "description": "Cuerpo inválido: placa o documento con formato incorrecto (code: bad_request)."
          },
          "401": {
            "description": "No autenticado o API key inválida (code: unauthorized)."
          },
          "402": {
            "description": "Sin créditos suficientes (code: no_credits)."
          },
          "404": {
            "description": "La fuente oficial respondió y no hay datos para la consulta. No reintentar: el resultado sería el mismo. code: propietario_no_coincide (el documento no es de un propietario activo del vehículo), vehiculo_no_registrado (el vehículo no tiene información registrada) o consulta_sin_resultado. Cada uno de esos códigos trae 10 consultas sin resultado gratis por mes y cuenta, con cuotas independientes; a partir de la 11 de ese código cobra como una consulta normal. Repetir una que ya salió sin resultado no cobra nunca (se responde de caché con fromCache: true). El body trae charged (si esta consulta cobró) y freeNoResultsLeft (cuántas gratis quedan en el mes para ESE código)."
          },
          "429": {
            "description": "Rate limit excedido: 1000 consultas/minuto por API key (code: rate_limited). Respeta Retry-After."
          },
          "500": {
            "description": "Error interno (code: internal_error)."
          },
          "502": {
            "description": "La fuente oficial no respondió a tiempo (code: source_error). Reintentar más tarde. No se cobra crédito."
          }
        }
      }
    },
    "/paz-salvo": {
      "post": {
        "operationId": "paz-salvo",
        "summary": "Paz y salvo de tránsito",
        "description": "Certificado de paz y salvo de tránsito de una persona por cédula (fuente SIMIT): indica si está a paz y salvo (sin comparendos ni deuda pendiente), el total adeudado y la cantidad de comparendos. `status` es ok a paz y salvo, warn si no. Paso previo típico de un trámite. No sustituye el certificado oficial del organismo de tránsito. Costo: 1 crédito por consulta con datos.",
        "x-credits": 1,
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "docType",
                  "docNumber"
                ],
                "properties": {
                  "docType": {
                    "type": "string",
                    "example": "CC",
                    "description": "Tipo de documento (CC, CE, NIT, PA, TI, CD, PPT, RC). Se aceptan alias comunes: PAS y PASAPORTE se normalizan a PA, y P.P.T. y P.P. se normalizan a PPT.",
                    "enum": [
                      "CC",
                      "CE",
                      "NIT",
                      "PA",
                      "TI",
                      "CD",
                      "PPT",
                      "RC"
                    ]
                  },
                  "docNumber": {
                    "type": "string",
                    "example": "1020304050",
                    "description": "Número de documento. Alias aceptado: `doc`."
                  },
                  "refresh": {
                    "type": "boolean",
                    "example": false,
                    "description": "Ignora la caché y vuelve a consultar la fuente oficial. Ojo: una consulta refrescada con datos siempre cobra (el hit de caché no)."
                  }
                }
              },
              "example": {
                "docType": "CC",
                "docNumber": "1020304050"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Consulta ejecutada. Cada fuente reporta su propio status (ok, empty, error).",
            "content": {
              "application/json": {
                "example": {
                  "source": "multas",
                  "status": "ok",
                  "data": {
                    "documentNumber": "1020304050",
                    "pazSalvo": true,
                    "totalDeuda": 0,
                    "totalComparendos": 0
                  },
                  "mode": "live",
                  "fetchedAt": "2026-07-24T15:04:05.000Z"
                }
              }
            }
          },
          "400": {
            "description": "Cuerpo inválido: placa o documento con formato incorrecto (code: bad_request)."
          },
          "401": {
            "description": "No autenticado o API key inválida (code: unauthorized)."
          },
          "402": {
            "description": "Sin créditos suficientes (code: no_credits)."
          },
          "404": {
            "description": "La fuente oficial respondió y no hay datos para la consulta. No reintentar: el resultado sería el mismo. code: propietario_no_coincide (el documento no es de un propietario activo del vehículo), vehiculo_no_registrado (el vehículo no tiene información registrada) o consulta_sin_resultado. Cada uno de esos códigos trae 10 consultas sin resultado gratis por mes y cuenta, con cuotas independientes; a partir de la 11 de ese código cobra como una consulta normal. Repetir una que ya salió sin resultado no cobra nunca (se responde de caché con fromCache: true). El body trae charged (si esta consulta cobró) y freeNoResultsLeft (cuántas gratis quedan en el mes para ESE código)."
          },
          "429": {
            "description": "Rate limit excedido: 1000 consultas/minuto por API key (code: rate_limited). Respeta Retry-After."
          },
          "500": {
            "description": "Error interno (code: internal_error)."
          },
          "502": {
            "description": "La fuente oficial no respondió a tiempo (code: source_error). Reintentar más tarde. No se cobra crédito."
          }
        }
      }
    },
    "/impuestos": {
      "post": {
        "operationId": "impuestos",
        "summary": "Impuesto vehicular",
        "description": "Departamento donde está matriculado el vehículo y enlace al portal oficial de impuestos. El departamento se resuelve desde el organismo de tránsito del RUNT por placa. NO liquida el impuesto: ningún departamento lo expone por API (todos blindan el portal con captcha y cuestionario), así que `data` siempre viene null y el valor está en `portalUrl` + el mensaje de `error`. Gratis: no cobra crédito. Gratis: no cobra crédito.",
        "x-credits": 0,
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "placa",
                  "docType",
                  "docNumber"
                ],
                "properties": {
                  "placa": {
                    "type": "string",
                    "example": "ABC123",
                    "description": "Placa del vehículo. 5 a 7 caracteres alfanuméricos: cubre AAA000, AAA00A y los formatos menos comunes (AAA00, AAAA00). Los guiones y espacios se ignoran."
                  },
                  "docType": {
                    "type": "string",
                    "example": "CC",
                    "description": "Tipo de documento del propietario (CC, CE, NIT, PA, TI, CD, PPT, RC). Se aceptan alias comunes: PAS y PASAPORTE se normalizan a PA, y P.P.T. y P.P. —como lo abrevia la tarjeta de propiedad— se normalizan a PPT.",
                    "enum": [
                      "CC",
                      "CE",
                      "NIT",
                      "PA",
                      "TI",
                      "CD",
                      "PPT",
                      "RC"
                    ]
                  },
                  "docNumber": {
                    "type": "string",
                    "example": "1020304050",
                    "description": "Número de documento del propietario. Alias aceptado: `doc`."
                  },
                  "refresh": {
                    "type": "boolean",
                    "example": false,
                    "description": "Ignora la caché y vuelve a consultar la fuente oficial. Ojo: una consulta refrescada con datos siempre cobra (el hit de caché no)."
                  }
                }
              },
              "example": {
                "placa": "ABC123",
                "docType": "CC",
                "docNumber": "1020304050"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Consulta ejecutada. Cada fuente reporta su propio status (ok, empty, error).",
            "content": {
              "application/json": {
                "example": {
                  "source": "Bogotá D.C.",
                  "status": "info",
                  "data": null,
                  "portalUrl": "https://www.haciendabogota.gov.co/es/sdh/pagos-impuesto-vehiculos",
                  "error": "Tu vehículo está matriculado en Bogotá D.C. Paga tu impuesto en el portal oficial del departamento.",
                  "mode": "live",
                  "fetchedAt": "2026-07-24T15:04:05.000Z"
                }
              }
            }
          },
          "400": {
            "description": "Cuerpo inválido: placa o documento con formato incorrecto (code: bad_request)."
          },
          "401": {
            "description": "No autenticado o API key inválida (code: unauthorized)."
          },
          "402": {
            "description": "Sin créditos suficientes (code: no_credits)."
          },
          "404": {
            "description": "La fuente oficial respondió y no hay datos para la consulta. No reintentar: el resultado sería el mismo. code: propietario_no_coincide (el documento no es de un propietario activo del vehículo), vehiculo_no_registrado (el vehículo no tiene información registrada) o consulta_sin_resultado. Cada uno de esos códigos trae 10 consultas sin resultado gratis por mes y cuenta, con cuotas independientes; a partir de la 11 de ese código cobra como una consulta normal. Repetir una que ya salió sin resultado no cobra nunca (se responde de caché con fromCache: true). El body trae charged (si esta consulta cobró) y freeNoResultsLeft (cuántas gratis quedan en el mes para ESE código)."
          },
          "429": {
            "description": "Rate limit excedido: 1000 consultas/minuto por API key (code: rate_limited). Respeta Retry-After."
          },
          "500": {
            "description": "Error interno (code: internal_error)."
          },
          "502": {
            "description": "La fuente oficial no respondió a tiempo (code: source_error). Reintentar más tarde. No se cobra crédito."
          }
        }
      }
    },
    "/avaluo": {
      "post": {
        "operationId": "avaluo",
        "summary": "Avalúo FASECOLDA",
        "description": "Valor comercial FASECOLDA y rango de mercado por placa: código FASECOLDA, marca, línea, modelo (año), valor comercial en pesos, rango min/max y clase. El VIN y el modelo se resuelven primero desde el RUNT, así que la placa basta. `origen` dice cómo se identificó el vehículo: `vin` (exacto) o `catalogo` (marca + año + línea + cilindraje, cuando FASECOLDA no decodifica el chasis — le pasa a los modelos nuevos); con `catalogo`, `aproximado` avisa si quedó más de una versión posible y el rango cubre todas. Valor de referencia del gremio asegurador, no un avalúo pericial. Costo: 1 crédito por consulta con datos.",
        "x-credits": 1,
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "placa",
                  "docType",
                  "docNumber"
                ],
                "properties": {
                  "placa": {
                    "type": "string",
                    "example": "ABC123",
                    "description": "Placa del vehículo. 5 a 7 caracteres alfanuméricos: cubre AAA000, AAA00A y los formatos menos comunes (AAA00, AAAA00). Los guiones y espacios se ignoran."
                  },
                  "docType": {
                    "type": "string",
                    "example": "CC",
                    "description": "Tipo de documento del propietario (CC, CE, NIT, PA, TI, CD, PPT, RC). Se aceptan alias comunes: PAS y PASAPORTE se normalizan a PA, y P.P.T. y P.P. —como lo abrevia la tarjeta de propiedad— se normalizan a PPT.",
                    "enum": [
                      "CC",
                      "CE",
                      "NIT",
                      "PA",
                      "TI",
                      "CD",
                      "PPT",
                      "RC"
                    ]
                  },
                  "docNumber": {
                    "type": "string",
                    "example": "1020304050",
                    "description": "Número de documento del propietario. Alias aceptado: `doc`."
                  },
                  "refresh": {
                    "type": "boolean",
                    "example": false,
                    "description": "Ignora la caché y vuelve a consultar la fuente oficial. Ojo: una consulta refrescada con datos siempre cobra (el hit de caché no)."
                  }
                }
              },
              "example": {
                "placa": "ABC123",
                "docType": "CC",
                "docNumber": "1020304050"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Consulta ejecutada. Cada fuente reporta su propio status (ok, empty, error).",
            "content": {
              "application/json": {
                "example": {
                  "source": "avaluo",
                  "status": "info",
                  "data": {
                    "codigo": "08053096",
                    "marca": "MAZDA",
                    "linea": "CX-30",
                    "modelo": 2023,
                    "valorComercial": 98000000,
                    "rangoMercado": {
                      "min": 92000000,
                      "max": 104000000
                    },
                    "clase": "CAMIONETA",
                    "origen": "vin"
                  },
                  "mode": "live",
                  "fetchedAt": "2026-07-24T15:04:05.000Z"
                }
              }
            }
          },
          "400": {
            "description": "Cuerpo inválido: placa o documento con formato incorrecto (code: bad_request)."
          },
          "401": {
            "description": "No autenticado o API key inválida (code: unauthorized)."
          },
          "402": {
            "description": "Sin créditos suficientes (code: no_credits)."
          },
          "404": {
            "description": "La fuente oficial respondió y no hay datos para la consulta. No reintentar: el resultado sería el mismo. code: propietario_no_coincide (el documento no es de un propietario activo del vehículo), vehiculo_no_registrado (el vehículo no tiene información registrada) o consulta_sin_resultado. Cada uno de esos códigos trae 10 consultas sin resultado gratis por mes y cuenta, con cuotas independientes; a partir de la 11 de ese código cobra como una consulta normal. Repetir una que ya salió sin resultado no cobra nunca (se responde de caché con fromCache: true). El body trae charged (si esta consulta cobró) y freeNoResultsLeft (cuántas gratis quedan en el mes para ESE código)."
          },
          "429": {
            "description": "Rate limit excedido: 1000 consultas/minuto por API key (code: rate_limited). Respeta Retry-After."
          },
          "500": {
            "description": "Error interno (code: internal_error)."
          },
          "502": {
            "description": "La fuente oficial no respondió a tiempo (code: source_error). Reintentar más tarde. No se cobra crédito."
          }
        }
      }
    },
    "/avaluo-por-codigo": {
      "post": {
        "operationId": "avaluo-por-codigo",
        "summary": "Avalúo FASECOLDA por código",
        "description": "Valor comercial FASECOLDA directo por código, sin resolver placa→código. Para aseguradoras y peritos que ya tienen el código FASECOLDA. Acepta `codeFasecolda` y opcionalmente `modelo` (año) para desambiguar el valor. Costo: 1 crédito por consulta con datos.",
        "x-credits": 1,
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "codeFasecolda"
                ],
                "properties": {
                  "codeFasecolda": {
                    "type": "string",
                    "example": "08053096",
                    "description": "Código FASECOLDA del vehículo (numérico). Alias aceptado: `codigo`."
                  },
                  "modelo": {
                    "type": "number",
                    "example": 2023,
                    "description": "Año del modelo; ajusta el valor comercial al año indicado."
                  },
                  "refresh": {
                    "type": "boolean",
                    "example": false,
                    "description": "Ignora la caché y vuelve a consultar la fuente oficial. Ojo: una consulta refrescada con datos siempre cobra (el hit de caché no)."
                  }
                }
              },
              "example": {
                "codeFasecolda": "08053096"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Consulta ejecutada. Cada fuente reporta su propio status (ok, empty, error).",
            "content": {
              "application/json": {
                "example": {
                  "source": "avaluo",
                  "status": "info",
                  "data": {
                    "codigo": "08053096",
                    "marca": "MAZDA",
                    "linea": "CX-30",
                    "modelo": 2023,
                    "valorComercial": 98000000,
                    "rangoMercado": {
                      "min": 92000000,
                      "max": 104000000
                    },
                    "clase": "CAMIONETA"
                  },
                  "mode": "live",
                  "fetchedAt": "2026-07-24T15:04:05.000Z"
                }
              }
            }
          },
          "400": {
            "description": "Cuerpo inválido: placa o documento con formato incorrecto (code: bad_request)."
          },
          "401": {
            "description": "No autenticado o API key inválida (code: unauthorized)."
          },
          "402": {
            "description": "Sin créditos suficientes (code: no_credits)."
          },
          "404": {
            "description": "La fuente oficial respondió y no hay datos para la consulta. No reintentar: el resultado sería el mismo. code: propietario_no_coincide (el documento no es de un propietario activo del vehículo), vehiculo_no_registrado (el vehículo no tiene información registrada) o consulta_sin_resultado. Cada uno de esos códigos trae 10 consultas sin resultado gratis por mes y cuenta, con cuotas independientes; a partir de la 11 de ese código cobra como una consulta normal. Repetir una que ya salió sin resultado no cobra nunca (se responde de caché con fromCache: true). El body trae charged (si esta consulta cobró) y freeNoResultsLeft (cuántas gratis quedan en el mes para ESE código)."
          },
          "429": {
            "description": "Rate limit excedido: 1000 consultas/minuto por API key (code: rate_limited). Respeta Retry-After."
          },
          "500": {
            "description": "Error interno (code: internal_error)."
          },
          "502": {
            "description": "La fuente oficial no respondió a tiempo (code: source_error). Reintentar más tarde. No se cobra crédito."
          }
        }
      }
    },
    "/catalogo": {
      "post": {
        "operationId": "catalogo",
        "summary": "Catálogo de marcas, modelos y versiones",
        "description": "Marcas, modelos, referencias y versiones de vehículos en Colombia, en cascada para poblar un selector: sin filtros trae las marcas y los años; con `marca`, sus referencias; con `marca` + `modelo` (o + `referencia`), las versiones. Cada versión trae su código —el mismo que acepta `/api/avaluo-por-codigo`—, el valor de mercado (`valorUsado`), el precio 0km (`valorNuevo`, solo en años que aún se venden nuevos) y la ficha técnica: cilindraje, potencia, airbags, puertas y tracción. No pide placa ni documento del propietario. Cada lista viene `null` cuando su filtro ya está decidido; con `listas=todas` vuelven todas. Un filtro que no existe en el catálogo responde 404 y no cobra. Costo: 1 crédito por consulta con datos.",
        "x-credits": 1,
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [],
                "properties": {
                  "categoria": {
                    "type": "string",
                    "example": "automovil",
                    "description": "Tipo de vehículo: `automovil` (default, incluye las SUV de pasajeros), `camioneta` (pickup y camioneta de carga), `moto` (incluye motocarro), `carga` (pesado de carga), `bus` (bus, buseta y microbús) o `remolque`. Los tres pesados comparten catálogo de marcas en la fuente, así que al elegir uno la lista de marcas puede incluir las de los otros dos; las versiones sí salen separadas."
                  },
                  "soloConPrecio": {
                    "type": "boolean",
                    "example": true,
                    "description": "`true` por defecto: solo devuelve las versiones con valor publicado para el año pedido. En `false` aparecen también las que existen sin precio para ese año (Toyota 2024 pasa de 44 a 401 versiones, casi todas en 0)."
                  },
                  "marca": {
                    "type": "string",
                    "example": "Toyota",
                    "description": "Marca por nombre (`Toyota`) o por id del catálogo (`178`). Sin tildes ni mayúsculas importa."
                  },
                  "modelo": {
                    "type": "string",
                    "example": "2024",
                    "description": "Año del modelo (`2024`). En el catálogo vehicular colombiano «modelo» es el año, no la línea."
                  },
                  "referencia": {
                    "type": "string",
                    "example": "Corolla",
                    "description": "Referencia/línea por nombre o id, resuelta dentro de la marca elegida. Admite prefijo: `Corolla` encuentra `COROLLA [12] [FL]`."
                  },
                  "listas": {
                    "type": "string",
                    "example": "todas",
                    "description": "`todas` devuelve `marcas`, `modelos` y `referencias` aunque su filtro ya esté decidido. Útil para repintar los tres selectores de un formulario con una sola llamada; por defecto cada lista se omite cuando ya elegiste ese filtro."
                  },
                  "pagina": {
                    "type": "number",
                    "example": 1,
                    "description": "Página de versiones (default 1)."
                  },
                  "porPagina": {
                    "type": "number",
                    "example": 50,
                    "description": "Versiones por página (default 50, máximo 200)."
                  },
                  "refresh": {
                    "type": "boolean",
                    "example": false,
                    "description": "Ignora la caché y vuelve a consultar la fuente oficial. Ojo: una consulta refrescada con datos siempre cobra (el hit de caché no)."
                  }
                }
              },
              "example": {
                "marca": "Toyota",
                "modelo": "2026"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Consulta ejecutada. Cada fuente reporta su propio status (ok, empty, error).",
            "content": {
              "application/json": {
                "example": {
                  "source": "catalogo",
                  "status": "info",
                  "data": {
                    "filtros": {
                      "categoria": {
                        "nombre": "automovil",
                        "etiqueta": "Automóvil"
                      },
                      "soloConPrecio": true,
                      "marca": {
                        "id": 178,
                        "nombre": "Toyota"
                      },
                      "modelo": {
                        "id": 41009,
                        "nombre": "2026"
                      },
                      "referencia": null
                    },
                    "marcas": null,
                    "modelos": null,
                    "referencias": [
                      {
                        "id": 211000,
                        "nombre": "Corolla [12] [fl]"
                      }
                    ],
                    "versiones": [
                      {
                        "codigo": "09033079",
                        "marca": "TOYOTA",
                        "referencia": "COROLLA [12] [FL]",
                        "version": "XE-I HYBRID",
                        "detalle": "TP 1800CC 7AB ABS",
                        "linea": "COROLLA [12] [FL] XE-I HYBRID TP 1800CC 7AB ABS",
                        "modelo": 2026,
                        "valorUsado": 130600000,
                        "valorNuevo": 122200000,
                        "valorComercial": 130600000,
                        "clase": "AUTOMOVIL",
                        "categoria": "LIVIANO PASAJEROS",
                        "tipologia": "SEDAN",
                        "combustible": "GASOLINA",
                        "transmision": "4X2",
                        "tipoCaja": "TIPTRONICA",
                        "cilindraje": 1798,
                        "potencia": 168,
                        "puertas": 4,
                        "airbags": 7,
                        "traccion": "DELANTERA",
                        "capacidadPasajeros": 5,
                        "peso": 1370
                      }
                    ],
                    "paginacion": {
                      "pagina": 1,
                      "porPagina": 50,
                      "paginas": 1,
                      "total": 4
                    }
                  },
                  "mode": "live",
                  "fetchedAt": "2026-07-24T15:04:05.000Z"
                }
              }
            }
          },
          "400": {
            "description": "Cuerpo inválido: placa o documento con formato incorrecto (code: bad_request)."
          },
          "401": {
            "description": "No autenticado o API key inválida (code: unauthorized)."
          },
          "402": {
            "description": "Sin créditos suficientes (code: no_credits)."
          },
          "404": {
            "description": "La fuente oficial respondió y no hay datos para la consulta. No reintentar: el resultado sería el mismo. code: propietario_no_coincide (el documento no es de un propietario activo del vehículo), vehiculo_no_registrado (el vehículo no tiene información registrada) o consulta_sin_resultado. Cada uno de esos códigos trae 10 consultas sin resultado gratis por mes y cuenta, con cuotas independientes; a partir de la 11 de ese código cobra como una consulta normal. Repetir una que ya salió sin resultado no cobra nunca (se responde de caché con fromCache: true). El body trae charged (si esta consulta cobró) y freeNoResultsLeft (cuántas gratis quedan en el mes para ESE código)."
          },
          "429": {
            "description": "Rate limit excedido: 1000 consultas/minuto por API key (code: rate_limited). Respeta Retry-After."
          },
          "500": {
            "description": "Error interno (code: internal_error)."
          },
          "502": {
            "description": "La fuente oficial no respondió a tiempo (code: source_error). Reintentar más tarde. No se cobra crédito."
          }
        }
      }
    },
    "/perdida-total": {
      "post": {
        "operationId": "perdida-total",
        "summary": "Pérdida total / siniestros",
        "description": "Historial de reclamaciones ante aseguradoras de un vehículo (fuente FASECOLDA, desde 2008): fecha, amparo y `severidad` de cada registro. Solo pide la placa. `severidad: \"mayor\"` = la aseguradora indemnizó el vehículo completo (pérdida total); `\"menor\"` = indemnizó una reparación; `\"desconocida\"` = amparo que la fuente no cataloga. `perdidaTotal` es true SOLO si hay al menos un registro de severidad mayor, así que un carro con reclamaciones menores devuelve `perdidaTotal: false` con `totalSiniestros > 0`. Cobertura parcial: cubre únicamente vehículos que estuvieron asegurados, así que `perdidaTotal: false` significa «no figura», no «nunca chocó». La fuente no informa el valor indemnizado ni la aseguradora. `status` es danger con pérdida total, warn con reclamaciones menores y ok sin registros. Cuesta 2 créditos (el scrape es lento y la fuente topa las consultas diarias). Costo: 2 créditos por consulta con datos.",
        "x-credits": 2,
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "placa"
                ],
                "properties": {
                  "placa": {
                    "type": "string",
                    "example": "ABC123",
                    "description": "Placa del vehículo. 5 a 7 caracteres alfanuméricos: cubre AAA000, AAA00A y los formatos menos comunes (AAA00, AAAA00). Los guiones y espacios se ignoran."
                  },
                  "refresh": {
                    "type": "boolean",
                    "example": false,
                    "description": "Ignora la caché y vuelve a consultar la fuente oficial. Ojo: una consulta refrescada con datos siempre cobra (el hit de caché no)."
                  }
                }
              },
              "example": {
                "placa": "ABC123"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Consulta ejecutada. Cada fuente reporta su propio status (ok, empty, error).",
            "content": {
              "application/json": {
                "example": {
                  "source": "siniestros",
                  "status": "danger",
                  "data": {
                    "placa": "ABC123",
                    "perdidaTotal": true,
                    "totalSiniestros": 2,
                    "siniestros": [
                      {
                        "fecha": "2022-09-13",
                        "amparo": "Pérdida Mayor Cuantía",
                        "severidad": "mayor"
                      },
                      {
                        "fecha": "2015-01-20",
                        "amparo": "Pérdida Menor Cuantía",
                        "severidad": "menor"
                      }
                    ],
                    "fuente": "Reclamaciones reportadas por aseguradoras",
                    "cobertura": "Solo vehículos que estuvieron asegurados; reclamaciones reportadas por las aseguradoras desde 2008."
                  },
                  "mode": "live",
                  "fetchedAt": "2026-07-24T15:04:05.000Z"
                }
              }
            }
          },
          "400": {
            "description": "Cuerpo inválido: placa o documento con formato incorrecto (code: bad_request)."
          },
          "401": {
            "description": "No autenticado o API key inválida (code: unauthorized)."
          },
          "402": {
            "description": "Sin créditos suficientes (code: no_credits)."
          },
          "404": {
            "description": "La fuente oficial respondió y no hay datos para la consulta. No reintentar: el resultado sería el mismo. code: propietario_no_coincide (el documento no es de un propietario activo del vehículo), vehiculo_no_registrado (el vehículo no tiene información registrada) o consulta_sin_resultado. Cada uno de esos códigos trae 10 consultas sin resultado gratis por mes y cuenta, con cuotas independientes; a partir de la 11 de ese código cobra como una consulta normal. Repetir una que ya salió sin resultado no cobra nunca (se responde de caché con fromCache: true). El body trae charged (si esta consulta cobró) y freeNoResultsLeft (cuántas gratis quedan en el mes para ESE código)."
          },
          "429": {
            "description": "Rate limit excedido: 1000 consultas/minuto por API key (code: rate_limited). Respeta Retry-After."
          },
          "500": {
            "description": "Error interno (code: internal_error)."
          },
          "502": {
            "description": "La fuente oficial no respondió a tiempo (code: source_error). Reintentar más tarde. No se cobra crédito."
          }
        }
      }
    },
    "/garantias-rgm": {
      "post": {
        "operationId": "garantias-rgm",
        "summary": "Prendas / garantías mobiliarias",
        "description": "Prendas inscritas sobre un vehículo en el RGM de Confecámaras, por placa. Da el detalle que el RUNT a veces no entrega cuando solo marca la bandera: acreedor(es), deudor/garante (nombre y documento), folio electrónico, fecha de inscripción (formato del portal, dd/mm/aaaa hh:mm:ss) y última operación (inscripción, modificación, ejecución). Sin prendas responde `tienePrenda: false` con `garantias: []`. Cuesta 1 crédito. Costo: 1 crédito por consulta con datos.",
        "x-credits": 1,
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "placa"
                ],
                "properties": {
                  "placa": {
                    "type": "string",
                    "example": "ABC123",
                    "description": "Placa del vehículo. 5 a 7 caracteres alfanuméricos: cubre AAA000, AAA00A y los formatos menos comunes (AAA00, AAAA00). Los guiones y espacios se ignoran."
                  },
                  "refresh": {
                    "type": "boolean",
                    "example": false,
                    "description": "Ignora la caché y vuelve a consultar la fuente oficial. Ojo: una consulta refrescada con datos siempre cobra (el hit de caché no)."
                  }
                }
              },
              "example": {
                "placa": "ABC123"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Consulta ejecutada. Cada fuente reporta su propio status (ok, empty, error).",
            "content": {
              "application/json": {
                "example": {
                  "source": "garantias",
                  "status": "warn",
                  "data": {
                    "placa": "ABC123",
                    "tienePrenda": true,
                    "garantias": [
                      {
                        "folio": "20210930000036900",
                        "acreedores": [
                          "RCI COLOMBIA S.A. COMPAÑIA DE FINANCIAMIENTO"
                        ],
                        "deudor": "JUAN PEREZ",
                        "docDeudor": "73140250",
                        "fechaInscripcion": "30/09/2021 10:55:38 a. m.",
                        "ultimaOperacion": "Formulario Registral de Modificación"
                      }
                    ],
                    "fuente": "Prendas y garantías mobiliarias registradas"
                  },
                  "mode": "live",
                  "fetchedAt": "2026-07-24T15:04:05.000Z"
                }
              }
            }
          },
          "400": {
            "description": "Cuerpo inválido: placa o documento con formato incorrecto (code: bad_request)."
          },
          "401": {
            "description": "No autenticado o API key inválida (code: unauthorized)."
          },
          "402": {
            "description": "Sin créditos suficientes (code: no_credits)."
          },
          "404": {
            "description": "La fuente oficial respondió y no hay datos para la consulta. No reintentar: el resultado sería el mismo. code: propietario_no_coincide (el documento no es de un propietario activo del vehículo), vehiculo_no_registrado (el vehículo no tiene información registrada) o consulta_sin_resultado. Cada uno de esos códigos trae 10 consultas sin resultado gratis por mes y cuenta, con cuotas independientes; a partir de la 11 de ese código cobra como una consulta normal. Repetir una que ya salió sin resultado no cobra nunca (se responde de caché con fromCache: true). El body trae charged (si esta consulta cobró) y freeNoResultsLeft (cuántas gratis quedan en el mes para ESE código)."
          },
          "429": {
            "description": "Rate limit excedido: 1000 consultas/minuto por API key (code: rate_limited). Respeta Retry-After."
          },
          "500": {
            "description": "Error interno (code: internal_error)."
          },
          "502": {
            "description": "La fuente oficial no respondió a tiempo (code: source_error). Reintentar más tarde. No se cobra crédito."
          }
        }
      }
    },
    "/pico-y-placa": {
      "post": {
        "operationId": "pico-y-placa",
        "summary": "Pico y placa",
        "description": "Restricción de pico y placa por ubicación y tipo de vehículo. Filtra por `ciudad` o por `lat`/`lng` (geolocaliza la ciudad; manda sobre `ciudad`). `tipoVehiculo` = carro (default) o moto. Qué dígito de la placa se evalúa lo fija el decreto de cada ciudad y viene en `digitoPlaca`: por defecto el último para carro y el primero para moto, pero no en todas: varias ciudades restringen también la moto por el último, así que hay que leer `digitoPlaca` en vez de asumir la regla. La `placa` es opcional: con placa indica si aplica hoy/mañana; sin placa devuelve qué dígitos restringen. Sin ubicación devuelve todas las ciudades monitoreadas. **En festivo nacional no hay pico y placa en ninguna ciudad**: `digitosHoy` sale vacío, `hoyAplica` en false y el bloque `festivo` trae el nombre del día. También viene incluido en consulta-full, con el mismo filtro por ubicación y el tipo de vehículo detectado solo desde el RUNT. Costo: 1 crédito por consulta con datos.",
        "x-credits": 1,
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [],
                "properties": {
                  "ciudad": {
                    "type": "string",
                    "example": "Bogotá",
                    "description": "Ciudad a consultar (ej. Bogotá)."
                  },
                  "lat": {
                    "type": "number",
                    "example": 4.65,
                    "description": "Latitud; requiere lng. Geolocaliza la ciudad y manda sobre `ciudad`."
                  },
                  "lng": {
                    "type": "number",
                    "example": -74.1,
                    "description": "Longitud; requiere lat."
                  },
                  "placa": {
                    "type": "string",
                    "example": "ABC123",
                    "description": "Placa; agrega hoyAplica/manianaAplica."
                  },
                  "tipoVehiculo": {
                    "type": "string",
                    "example": "carro",
                    "description": "carro (default) | moto. El dígito que se evalúa lo decide cada ciudad y se devuelve en `digitoPlaca`. taxi y publico se aceptan pero aún no tienen reglas cargadas (devuelven tienePicoYPlaca:false)."
                  }
                }
              },
              "example": {
                "ciudad": "Bogotá",
                "placa": "ABC123"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Consulta ejecutada. Cada fuente reporta su propio status (ok, empty, error).",
            "content": {
              "application/json": {
                "example": {
                  "source": "pico-y-placa",
                  "status": "ok",
                  "ubicacion": {
                    "matched": true,
                    "source": "ciudad",
                    "consulta": {
                      "ciudad": "Bogotá"
                    },
                    "ciudad": "Bogotá",
                    "departamento": "Bogotá D.C."
                  },
                  "festivo": {
                    "hoy": null,
                    "maniana": null
                  },
                  "data": [
                    {
                      "ciudad": "Bogotá",
                      "departamento": "Bogotá D.C.",
                      "tipoVehiculo": "carro",
                      "digitoPlaca": "ultimo",
                      "tienePicoYPlaca": true,
                      "esquema": "parImpar",
                      "hoyAplica": false,
                      "manianaAplica": true,
                      "digitosHoy": [
                        1,
                        2,
                        3,
                        4,
                        5
                      ],
                      "digitosManiana": [
                        6,
                        7,
                        8,
                        9,
                        0
                      ],
                      "diasSemana": [],
                      "horarios": "L–V, 6:00–21:00",
                      "vigencia": "Vigente en julio de 2026",
                      "fuente": "https://www.movilidadbogota.gov.co/pico-y-placa"
                    }
                  ],
                  "mode": "live",
                  "fetchedAt": "2026-07-24T15:04:05.000Z"
                }
              }
            }
          },
          "400": {
            "description": "Cuerpo inválido: placa o documento con formato incorrecto (code: bad_request)."
          },
          "401": {
            "description": "No autenticado o API key inválida (code: unauthorized)."
          },
          "402": {
            "description": "Sin créditos suficientes (code: no_credits)."
          },
          "404": {
            "description": "La fuente oficial respondió y no hay datos para la consulta. No reintentar: el resultado sería el mismo. code: propietario_no_coincide (el documento no es de un propietario activo del vehículo), vehiculo_no_registrado (el vehículo no tiene información registrada) o consulta_sin_resultado. Cada uno de esos códigos trae 10 consultas sin resultado gratis por mes y cuenta, con cuotas independientes; a partir de la 11 de ese código cobra como una consulta normal. Repetir una que ya salió sin resultado no cobra nunca (se responde de caché con fromCache: true). El body trae charged (si esta consulta cobró) y freeNoResultsLeft (cuántas gratis quedan en el mes para ESE código)."
          },
          "429": {
            "description": "Rate limit excedido: 1000 consultas/minuto por API key (code: rate_limited). Respeta Retry-After."
          },
          "500": {
            "description": "Error interno (code: internal_error)."
          },
          "502": {
            "description": "La fuente oficial no respondió a tiempo (code: source_error). Reintentar más tarde. No se cobra crédito."
          }
        }
      }
    },
    "/licencia": {
      "post": {
        "operationId": "licencia",
        "summary": "Licencias de conducción",
        "description": "Licencias de conducción por cédula (RUNT ciudadano): datos del conductor (nombre, estado de conductor y de ciudadano, número y fecha de inscripción), el arreglo `licenses` con una entrada por categoría —categoría, estado, número, organismo que expide, expedición, vencimiento, restricciones y, si aplica, resolución y fechas de suspensión— y los bloques de infracciones, solicitudes, certificados de aptitud y médicos, trámites SICOV, pagos ANSV, validaciones de identidad e impuestos de tránsito. Los bloques que el RUNT devuelve vacíos para la mayoría de documentos llegan como arreglos vacíos, no como null. Desde el 6-ago-2026 la fuente oficial exige el `primerApellido` del titular y devuelve el nombre ENMASCARADO (`J**N P***Z`): si no mandas el apellido se intenta resolver, y si no se logra la respuesta es 400 `apellido_requerido` sin cobrar. Costo: 1 crédito por consulta con datos.",
        "x-credits": 1,
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "docType",
                  "docNumber"
                ],
                "properties": {
                  "docType": {
                    "type": "string",
                    "example": "CC",
                    "description": "Tipo de documento (CC, CE, NIT, PA, TI, CD, PPT, RC). Se aceptan alias comunes: PAS y PASAPORTE se normalizan a PA, y P.P.T. y P.P. se normalizan a PPT.",
                    "enum": [
                      "CC",
                      "CE",
                      "NIT",
                      "PA",
                      "TI",
                      "CD",
                      "PPT",
                      "RC"
                    ]
                  },
                  "docNumber": {
                    "type": "string",
                    "example": "1020304050",
                    "description": "Número de documento. Alias aceptado: `doc`."
                  },
                  "primerApellido": {
                    "type": "string",
                    "example": "PÉREZ",
                    "description": "Primer apellido del titular del documento. La fuente oficial lo exige desde el 6-ago-2026: si no lo mandas se intenta resolver y, si no se logra, la respuesta es 400 con `code: \"apellido_requerido\"` y NO se cobra el crédito. Alias aceptado: `apellido`."
                  },
                  "refresh": {
                    "type": "boolean",
                    "example": false,
                    "description": "Ignora la caché y vuelve a consultar la fuente oficial. Ojo: una consulta refrescada con datos siempre cobra (el hit de caché no)."
                  }
                }
              },
              "example": {
                "docType": "CC",
                "docNumber": "1020304050",
                "primerApellido": "PÉREZ"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Consulta ejecutada. Cada fuente reporta su propio status (ok, empty, error).",
            "content": {
              "application/json": {
                "example": {
                  "data": {
                    "documentType": "CC",
                    "documentNumber": "1020304050",
                    "fullName": "J**N P***Z",
                    "driverStatus": "ACTIVO",
                    "citizenStatus": "ACTIVA",
                    "inscriptionNumber": "20310213",
                    "inscriptionDate": "08/02/2021",
                    "consultationDateTime": "11/07/2026",
                    "totalLicenses": "1",
                    "licenses": [
                      {
                        "category": "B1",
                        "status": "ACTIVA",
                        "licenceNumber": "1020304050",
                        "otExpide": "INSTITUTO DE MOVILIDAD",
                        "expeditionDate": "23/04/2025",
                        "dueDate": "23/04/2035",
                        "examExpirationDate": null,
                        "restrictions": null,
                        "authorityTransit": null,
                        "resolutionNumber": null,
                        "startDateSuspension": null,
                        "endDateSuspension": null,
                        "substratum": "1020304050"
                      }
                    ],
                    "infractions": {
                      "tieneMultas": "NO",
                      "nroPazYSalvo": "885466652067"
                    },
                    "requests": [],
                    "aptitudeCertificates": [],
                    "medicalCertificates": [],
                    "sicovRequests": [],
                    "ANSVpayments": [],
                    "identityValidationAttempts": {
                      "estadoUsuario": "ACTIVO",
                      "fechaDesbloqueo": null,
                      "validaciones": []
                    },
                    "identityValidationRequests": {
                      "estadoUsuario": "ACTIVO",
                      "fechaDesbloqueo": null,
                      "validaciones": []
                    },
                    "transitTaxes": {}
                  },
                  "mode": "live",
                  "fetchedAt": "2026-07-24T15:04:05.000Z"
                }
              }
            }
          },
          "400": {
            "description": "Cuerpo inválido: placa o documento con formato incorrecto (code: bad_request)."
          },
          "401": {
            "description": "No autenticado o API key inválida (code: unauthorized)."
          },
          "402": {
            "description": "Sin créditos suficientes (code: no_credits)."
          },
          "404": {
            "description": "La fuente oficial respondió y no hay datos para la consulta. No reintentar: el resultado sería el mismo. code: propietario_no_coincide (el documento no es de un propietario activo del vehículo), vehiculo_no_registrado (el vehículo no tiene información registrada) o consulta_sin_resultado. Cada uno de esos códigos trae 10 consultas sin resultado gratis por mes y cuenta, con cuotas independientes; a partir de la 11 de ese código cobra como una consulta normal. Repetir una que ya salió sin resultado no cobra nunca (se responde de caché con fromCache: true). El body trae charged (si esta consulta cobró) y freeNoResultsLeft (cuántas gratis quedan en el mes para ESE código)."
          },
          "429": {
            "description": "Rate limit excedido: 1000 consultas/minuto por API key (code: rate_limited). Respeta Retry-After."
          },
          "500": {
            "description": "Error interno (code: internal_error)."
          },
          "502": {
            "description": "La fuente oficial no respondió a tiempo (code: source_error). Reintentar más tarde. No se cobra crédito."
          }
        }
      }
    },
    "/vehiculo-pe": {
      "post": {
        "operationId": "vehiculo-pe",
        "summary": "Vehículo Perú",
        "description": "Ficha técnica de un vehículo peruano por placa, desde el registro oficial de propiedad vehicular. Devuelve los 13 campos canónicos comunes a todos los países; en Perú el registro publica 5 de ellos y el resto llega en `null`, listados en `cobertura.noPublicados`. Una placa fuera del registro responde `no_encontrado`. No incluye datos del propietario. Cuesta 1 crédito. Costo: 1 crédito por consulta con datos.",
        "x-credits": 1,
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "placa"
                ],
                "properties": {
                  "placa": {
                    "type": "string",
                    "example": "ABC123",
                    "description": "Placa peruana. Se aceptan guiones (`ABC-123`)."
                  },
                  "refresh": {
                    "type": "boolean",
                    "example": false,
                    "description": "Ignora la caché y vuelve a consultar la fuente oficial. Ojo: una consulta refrescada con datos siempre cobra (el hit de caché no)."
                  }
                }
              },
              "example": {
                "placa": "ABC123"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Consulta ejecutada. Cada fuente reporta su propio status (ok, empty, error).",
            "content": {
              "application/json": {
                "example": {
                  "source": "vehiculo",
                  "status": "ok",
                  "data": {
                    "pais": "PE",
                    "placa": "ABC123",
                    "clase": null,
                    "tipo": null,
                    "carroceria": null,
                    "marca": "SUZUKI",
                    "linea": "GRAND NOMADE",
                    "capacidadPasajeros": null,
                    "capacidadCargaKg": null,
                    "color": "GRIS",
                    "modelo": 2010,
                    "servicioPublico": null,
                    "vin": "JS3TE04V2A4602091",
                    "combustible": null,
                    "cilindraje": null
                  },
                  "cobertura": {
                    "disponibles": [
                      "marca",
                      "linea",
                      "color",
                      "modelo",
                      "vin"
                    ],
                    "noPublicados": [
                      "clase",
                      "tipo",
                      "carroceria",
                      "capacidadPasajeros",
                      "capacidadCargaKg",
                      "servicioPublico",
                      "combustible",
                      "cilindraje"
                    ]
                  },
                  "portalUrl": "https://consultavehicular.sunarp.gob.pe/consulta-vehicular/inicio",
                  "mode": "live",
                  "fetchedAt": "2026-07-24T15:04:05.000Z"
                }
              }
            }
          },
          "400": {
            "description": "Cuerpo inválido: placa o documento con formato incorrecto (code: bad_request)."
          },
          "401": {
            "description": "No autenticado o API key inválida (code: unauthorized)."
          },
          "402": {
            "description": "Sin créditos suficientes (code: no_credits)."
          },
          "404": {
            "description": "La fuente oficial respondió y no hay datos para la consulta. No reintentar: el resultado sería el mismo. code: propietario_no_coincide (el documento no es de un propietario activo del vehículo), vehiculo_no_registrado (el vehículo no tiene información registrada) o consulta_sin_resultado. Cada uno de esos códigos trae 10 consultas sin resultado gratis por mes y cuenta, con cuotas independientes; a partir de la 11 de ese código cobra como una consulta normal. Repetir una que ya salió sin resultado no cobra nunca (se responde de caché con fromCache: true). El body trae charged (si esta consulta cobró) y freeNoResultsLeft (cuántas gratis quedan en el mes para ESE código)."
          },
          "429": {
            "description": "Rate limit excedido: 1000 consultas/minuto por API key (code: rate_limited). Respeta Retry-After."
          },
          "500": {
            "description": "Error interno (code: internal_error)."
          },
          "502": {
            "description": "La fuente oficial no respondió a tiempo (code: source_error). Reintentar más tarde. No se cobra crédito."
          }
        }
      }
    },
    "/vehiculo-mx": {
      "post": {
        "operationId": "vehiculo-mx",
        "summary": "Vehículo México",
        "description": "Ficha técnica de un vehículo mexicano por placa, desde el registro público vehicular nacional, más su estado de robo cruzado contra cuatro fuentes: fiscalía, aseguradoras, avisos ministeriales y el registro de robo de EE. UU./Canadá. Devuelve los 13 campos canónicos comunes a todos los países; los que el registro no publica llegan en `null` y quedan listados en `cobertura.noPublicados`. Un vehículo fuera del padrón responde `no_inscrito` (la cobertura del registro es parcial y eso no es un error). No incluye datos del propietario. Cuesta 1 crédito. Costo: 1 crédito por consulta con datos.",
        "x-credits": 1,
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "placa"
                ],
                "properties": {
                  "placa": {
                    "type": "string",
                    "example": "ABC1234",
                    "description": "Placa mexicana, sin guiones ni espacios."
                  },
                  "refresh": {
                    "type": "boolean",
                    "example": false,
                    "description": "Ignora la caché y vuelve a consultar la fuente oficial. Ojo: una consulta refrescada con datos siempre cobra (el hit de caché no)."
                  }
                }
              },
              "example": {
                "placa": "ABC1234"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Consulta ejecutada. Cada fuente reporta su propio status (ok, empty, error).",
            "content": {
              "application/json": {
                "example": {
                  "source": "vehiculo",
                  "status": "ok",
                  "data": {
                    "pais": "MX",
                    "placa": "ABC1234",
                    "clase": "AUTOMOVIL",
                    "tipo": null,
                    "carroceria": "HATCHBACK",
                    "marca": "BMW",
                    "linea": "120IA",
                    "capacidadPasajeros": null,
                    "capacidadCargaKg": null,
                    "color": null,
                    "modelo": 2019,
                    "servicioPublico": null,
                    "vin": "WBA1S1106K7D61956",
                    "combustible": null,
                    "cilindraje": null,
                    "reporteRobo": {
                      "reportado": false,
                      "fuentes": {
                        "fiscalia": false,
                        "ocra": false,
                        "usaCanada": false,
                        "avisosJudiciales": false
                      }
                    }
                  },
                  "cobertura": {
                    "disponibles": [
                      "clase",
                      "carroceria",
                      "marca",
                      "linea",
                      "modelo",
                      "vin",
                      "cilindraje"
                    ],
                    "noPublicados": [
                      "tipo",
                      "capacidadPasajeros",
                      "capacidadCargaKg",
                      "color",
                      "servicioPublico",
                      "combustible"
                    ]
                  },
                  "portalUrl": "https://www2.repuve.gob.mx:8443/ciudadania/",
                  "mode": "live",
                  "fetchedAt": "2026-07-24T15:04:05.000Z"
                }
              }
            }
          },
          "400": {
            "description": "Cuerpo inválido: placa o documento con formato incorrecto (code: bad_request)."
          },
          "401": {
            "description": "No autenticado o API key inválida (code: unauthorized)."
          },
          "402": {
            "description": "Sin créditos suficientes (code: no_credits)."
          },
          "404": {
            "description": "La fuente oficial respondió y no hay datos para la consulta. No reintentar: el resultado sería el mismo. code: propietario_no_coincide (el documento no es de un propietario activo del vehículo), vehiculo_no_registrado (el vehículo no tiene información registrada) o consulta_sin_resultado. Cada uno de esos códigos trae 10 consultas sin resultado gratis por mes y cuenta, con cuotas independientes; a partir de la 11 de ese código cobra como una consulta normal. Repetir una que ya salió sin resultado no cobra nunca (se responde de caché con fromCache: true). El body trae charged (si esta consulta cobró) y freeNoResultsLeft (cuántas gratis quedan en el mes para ESE código)."
          },
          "429": {
            "description": "Rate limit excedido: 1000 consultas/minuto por API key (code: rate_limited). Respeta Retry-After."
          },
          "500": {
            "description": "Error interno (code: internal_error)."
          },
          "502": {
            "description": "La fuente oficial no respondió a tiempo (code: source_error). Reintentar más tarde. No se cobra crédito."
          }
        }
      }
    },
    "/antecedentes-disciplinarios": {
      "post": {
        "operationId": "antecedentes-disciplinarios",
        "summary": "Antecedentes disciplinarios",
        "description": "Antecedentes disciplinarios de una persona por documento, del sistema SIRI de la Procuraduría General de la Nación. Devuelve si registra sanciones o inhabilidades vigentes, el nombre completo del titular y el número del certificado para verificarlo ante la entidad. Cuando hay anotaciones vienen ESTRUCTURADAS —sanción, término, clase, delitos, providencia (autoridad y fechas) e inhabilidades con su vigencia—, no como bloque de texto. `inhabilitadoHasta` resume la fecha más lejana de todas: es lo que responde \"¿puedo vincular a esta persona hoy?\" sin recorrer el resto (un certificado real trajo 323 anotaciones, y `anotaciones` viene topada en 50 con el conteo real en `totalAnotaciones`). Sin antecedentes responde `tieneAntecedentes: false` — y esa respuesta también cobra: es el dato que se necesita para contratar o vincular a alguien. Cuesta 1 crédito. Costo: 1 crédito por consulta con datos.",
        "x-credits": 1,
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "docType",
                  "docNumber"
                ],
                "properties": {
                  "docType": {
                    "type": "string",
                    "example": "CC",
                    "description": "Tipo de documento. Esta fuente maneja CC, CE, NIT, PPT y PEP; con PA, TI, CD o RC responde 400 `tipo_documento_no_soportado`.",
                    "enum": [
                      "CC",
                      "CE",
                      "NIT",
                      "PPT",
                      "PEP"
                    ]
                  },
                  "docNumber": {
                    "type": "string",
                    "example": "1020304050",
                    "description": "Número de documento. Alias aceptado: `doc`."
                  },
                  "primerNombre": {
                    "type": "string",
                    "example": "JUAN",
                    "description": "Primer nombre del titular. OPCIONAL y no lo exige la fuente: solo ahorra un par de peticiones al resolver la pregunta de seguridad del portal. No cambia el resultado ni la caché."
                  },
                  "refresh": {
                    "type": "boolean",
                    "example": false,
                    "description": "Ignora la caché y vuelve a consultar la fuente oficial. Ojo: una consulta refrescada con datos siempre cobra (el hit de caché no)."
                  }
                }
              },
              "example": {
                "docType": "CC",
                "docNumber": "1020304050"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Consulta ejecutada. Cada fuente reporta su propio status (ok, empty, error).",
            "content": {
              "application/json": {
                "example": {
                  "source": "antecedentes-disciplinarios",
                  "status": "danger",
                  "data": {
                    "documento": "1020304050",
                    "tipoDocumento": "Cédula de ciudadanía",
                    "nombre": "JUAN PEREZ GOMEZ",
                    "tieneAntecedentes": true,
                    "descripcion": "Registra sanciones o inhabilidades vigentes",
                    "anotaciones": [
                      {
                        "tipo": "SANCIONES PENALES",
                        "registroSiri": "201221493",
                        "sanciones": [
                          {
                            "sancion": "PRISION",
                            "termino": "8 AÑOS",
                            "clase": "PRINCIPAL",
                            "suspendida": ""
                          }
                        ],
                        "delitos": [
                          "LAVADO DE ACTIVOS (LEY 599 DE 2000)"
                        ],
                        "providencias": [
                          {
                            "instancia": "PRIMERA",
                            "autoridad": "JUZGADO 1 PENAL DEL CIRCUITO - BUGA (VALLE DEL CAUCA)",
                            "fechaProvidencia": "06/09/2017",
                            "fechaEfectosJuridicos": "11/06/2019"
                          }
                        ],
                        "inhabilidades": [
                          {
                            "modulo": "PENAL",
                            "inhabilidad": "INHABILIDAD PARA DESEMPEÑAR CARGOS PÚBLICOS LEY 1952 DE 2019 ART 42",
                            "fechaInicio": "11/06/2019",
                            "fechaFin": "10/06/2027"
                          }
                        ]
                      }
                    ],
                    "totalAnotaciones": 1,
                    "inhabilitadoHasta": "10/06/2027",
                    "certificadoNumero": "301011498",
                    "fechaExpedicion": "11 de agosto del 2026"
                  },
                  "mode": "live",
                  "fetchedAt": "2026-07-24T15:04:05.000Z",
                  "cost": 1
                }
              }
            }
          },
          "400": {
            "description": "Cuerpo inválido: placa o documento con formato incorrecto (code: bad_request)."
          },
          "401": {
            "description": "No autenticado o API key inválida (code: unauthorized)."
          },
          "402": {
            "description": "Sin créditos suficientes (code: no_credits)."
          },
          "404": {
            "description": "La fuente oficial respondió y no hay datos para la consulta. No reintentar: el resultado sería el mismo. code: propietario_no_coincide (el documento no es de un propietario activo del vehículo), vehiculo_no_registrado (el vehículo no tiene información registrada) o consulta_sin_resultado. Cada uno de esos códigos trae 10 consultas sin resultado gratis por mes y cuenta, con cuotas independientes; a partir de la 11 de ese código cobra como una consulta normal. Repetir una que ya salió sin resultado no cobra nunca (se responde de caché con fromCache: true). El body trae charged (si esta consulta cobró) y freeNoResultsLeft (cuántas gratis quedan en el mes para ESE código)."
          },
          "429": {
            "description": "Rate limit excedido: 1000 consultas/minuto por API key (code: rate_limited). Respeta Retry-After."
          },
          "500": {
            "description": "Error interno (code: internal_error)."
          },
          "502": {
            "description": "La fuente oficial no respondió a tiempo (code: source_error). Reintentar más tarde. No se cobra crédito."
          }
        }
      }
    },
    "/antecedentes-fiscales": {
      "post": {
        "operationId": "antecedentes-fiscales",
        "summary": "Antecedentes fiscales",
        "description": "Antecedentes fiscales de una persona natural por documento, del Boletín de Responsables Fiscales (SIBOR) de la Contraloría General de la República. Devuelve si está reportada como responsable fiscal y el código con el que se comprueba la autenticidad del certificado ante la entidad. Es el requisito para contratar con el Estado y para posesionarse en cargos públicos. Cuesta 1 crédito. Costo: 1 crédito por consulta con datos.",
        "x-credits": 1,
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "docType",
                  "docNumber"
                ],
                "properties": {
                  "docType": {
                    "type": "string",
                    "example": "CC",
                    "description": "Tipo de documento. Esta fuente maneja CC, CE, TI, PA, PPT y PEP (personas naturales). Con NIT, CD o RC responde 400 `tipo_documento_no_soportado`: las personas jurídicas se certifican por otra vía.",
                    "enum": [
                      "CC",
                      "CE",
                      "TI",
                      "PA",
                      "PPT",
                      "PEP"
                    ]
                  },
                  "docNumber": {
                    "type": "string",
                    "example": "1020304050",
                    "description": "Número de documento. Alias aceptado: `doc`."
                  },
                  "refresh": {
                    "type": "boolean",
                    "example": false,
                    "description": "Ignora la caché y vuelve a consultar la fuente oficial. Ojo: una consulta refrescada con datos siempre cobra (el hit de caché no)."
                  }
                }
              },
              "example": {
                "docType": "CC",
                "docNumber": "1020304050"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Consulta ejecutada. Cada fuente reporta su propio status (ok, empty, error).",
            "content": {
              "application/json": {
                "example": {
                  "source": "antecedentes-fiscales",
                  "status": "ok",
                  "data": {
                    "documento": "1020304050",
                    "tipoDocumento": "Cédula de Ciudadanía",
                    "tieneAntecedentes": false,
                    "descripcion": "No se encuentra reportado como responsable fiscal",
                    "codigoVerificacion": "1020304050260811171708",
                    "fechaConsulta": "martes 11 de agosto de 2026 17:17:08"
                  },
                  "mode": "live",
                  "fetchedAt": "2026-07-24T15:04:05.000Z",
                  "cost": 1
                }
              }
            }
          },
          "400": {
            "description": "Cuerpo inválido: placa o documento con formato incorrecto (code: bad_request)."
          },
          "401": {
            "description": "No autenticado o API key inválida (code: unauthorized)."
          },
          "402": {
            "description": "Sin créditos suficientes (code: no_credits)."
          },
          "404": {
            "description": "La fuente oficial respondió y no hay datos para la consulta. No reintentar: el resultado sería el mismo. code: propietario_no_coincide (el documento no es de un propietario activo del vehículo), vehiculo_no_registrado (el vehículo no tiene información registrada) o consulta_sin_resultado. Cada uno de esos códigos trae 10 consultas sin resultado gratis por mes y cuenta, con cuotas independientes; a partir de la 11 de ese código cobra como una consulta normal. Repetir una que ya salió sin resultado no cobra nunca (se responde de caché con fromCache: true). El body trae charged (si esta consulta cobró) y freeNoResultsLeft (cuántas gratis quedan en el mes para ESE código)."
          },
          "429": {
            "description": "Rate limit excedido: 1000 consultas/minuto por API key (code: rate_limited). Respeta Retry-After."
          },
          "500": {
            "description": "Error interno (code: internal_error)."
          },
          "502": {
            "description": "La fuente oficial no respondió a tiempo (code: source_error). Reintentar más tarde. No se cobra crédito."
          }
        }
      }
    },
    "/antecedentes-judiciales": {
      "post": {
        "operationId": "antecedentes-judiciales",
        "summary": "Antecedentes judiciales",
        "description": "Antecedentes judiciales de una persona por documento, del sistema de la Policía Nacional. Certifica si la persona **tiene asuntos pendientes con las autoridades judiciales HOY**; por la Sentencia SU-458 de 2012 la consulta de terceros no revela condenas ya cumplidas o prescritas, así que no es un historial penal. `descripcion` trae la leyenda textual del registro, que tiene dos formas para el caso sin asuntos pendientes y no son intercambiables: conviene leerla, no solo la bandera. Devuelve además el nombre del titular en orden apellidos-nombres. **`nombre` vacío es una señal, no un hueco**: el registro omite esa línea cuando el documento no figura en la Registraduría. **Cuesta 2 créditos**: es el único endpoint de la familia que paga un resolvedor de captcha en cada consulta viva. Un hit de caché no cobra, y si la fuente falla se devuelven los 2. Costo: 2 créditos por consulta con datos.",
        "x-credits": 2,
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "docType",
                  "docNumber"
                ],
                "properties": {
                  "docType": {
                    "type": "string",
                    "example": "CC",
                    "description": "Tipo de documento. Esta fuente maneja CC, CE, PA y CD (documento de país de origen). Con NIT, TI, PPT, RC o PEP responde 400 `tipo_documento_no_soportado`.",
                    "enum": [
                      "CC",
                      "CE",
                      "PA",
                      "CD"
                    ]
                  },
                  "docNumber": {
                    "type": "string",
                    "example": "1020304050",
                    "description": "Número de documento. Alias aceptado: `doc`."
                  },
                  "refresh": {
                    "type": "boolean",
                    "example": false,
                    "description": "Ignora la caché y vuelve a consultar la fuente oficial. Ojo: una consulta refrescada con datos siempre cobra (el hit de caché no)."
                  }
                }
              },
              "example": {
                "docType": "CC",
                "docNumber": "1020304050"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Consulta ejecutada. Cada fuente reporta su propio status (ok, empty, error).",
            "content": {
              "application/json": {
                "example": {
                  "source": "antecedentes-judiciales",
                  "status": "ok",
                  "data": {
                    "documento": "1020304050",
                    "nombre": "PEREZ GOMEZ JUAN CARLOS",
                    "tipoDocumento": "Cédula de Ciudadanía",
                    "tieneAntecedentes": false,
                    "descripcion": "No tiene asuntos pendientes con las autoridades judiciales",
                    "anotaciones": [],
                    "fechaConsulta": "11/08/2026 05:50:05 PM"
                  },
                  "mode": "live",
                  "fetchedAt": "2026-07-24T15:04:05.000Z",
                  "cost": 2
                }
              }
            }
          },
          "400": {
            "description": "Cuerpo inválido: placa o documento con formato incorrecto (code: bad_request)."
          },
          "401": {
            "description": "No autenticado o API key inválida (code: unauthorized)."
          },
          "402": {
            "description": "Sin créditos suficientes (code: no_credits)."
          },
          "404": {
            "description": "La fuente oficial respondió y no hay datos para la consulta. No reintentar: el resultado sería el mismo. code: propietario_no_coincide (el documento no es de un propietario activo del vehículo), vehiculo_no_registrado (el vehículo no tiene información registrada) o consulta_sin_resultado. Cada uno de esos códigos trae 10 consultas sin resultado gratis por mes y cuenta, con cuotas independientes; a partir de la 11 de ese código cobra como una consulta normal. Repetir una que ya salió sin resultado no cobra nunca (se responde de caché con fromCache: true). El body trae charged (si esta consulta cobró) y freeNoResultsLeft (cuántas gratis quedan en el mes para ESE código)."
          },
          "429": {
            "description": "Rate limit excedido: 1000 consultas/minuto por API key (code: rate_limited). Respeta Retry-After."
          },
          "500": {
            "description": "Error interno (code: internal_error)."
          },
          "502": {
            "description": "La fuente oficial no respondió a tiempo (code: source_error). Reintentar más tarde. No se cobra crédito."
          }
        }
      }
    },
    "/listas-restrictivas": {
      "post": {
        "operationId": "listas-restrictivas",
        "summary": "Listas restrictivas (OFAC)",
        "description": "Búsqueda de una persona o empresa en las listas de sanciones de OFAC (Departamento del Tesoro de EE. UU.): la lista SDN —la \"lista Clinton\"— y las listas consolidadas no-SDN. Se consulta POR NOMBRE, no por documento: estas listas no manejan cédulas. Devuelve cada coincidencia con su puntaje 0–1, el programa de sanciones, la lista de origen y si el emparejamiento fue contra un alias (a.k.a.). La búsqueda cubre también los ~21.000 alias registrados, que es donde aparecen las variantes de escritura. Cuesta 1 crédito. Costo: 1 crédito por consulta con datos.",
        "x-credits": 1,
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "nombre"
                ],
                "properties": {
                  "nombre": {
                    "type": "string",
                    "example": "JUAN PEREZ GOMEZ",
                    "description": "Nombre completo de la persona o razón social. El orden no importa: la comparación es por palabras, sin tildes ni puntuación. Se exige que TODAS las palabras del nombre aparezcan en el registro, así que apellidos sueltos devuelven muchas coincidencias y nombres completos muy pocas."
                  },
                  "refresh": {
                    "type": "boolean",
                    "example": false,
                    "description": "Ignora la caché y vuelve a consultar la fuente oficial. Ojo: una consulta refrescada con datos siempre cobra (el hit de caché no)."
                  }
                }
              },
              "example": {
                "nombre": "JUAN PEREZ GOMEZ"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Consulta ejecutada. Cada fuente reporta su propio status (ok, empty, error).",
            "content": {
              "application/json": {
                "example": {
                  "source": "listas-restrictivas",
                  "status": "danger",
                  "data": {
                    "nombreConsultado": "JUAN PEREZ GOMEZ",
                    "tieneAntecedentes": true,
                    "descripcion": "Coincide con 1 registro(s) de las listas de sanciones",
                    "enListas": true,
                    "totalCoincidencias": 1,
                    "coincidencias": [
                      {
                        "nombre": "PEREZ GOMEZ, Juan",
                        "tipo": "individual",
                        "programas": [
                          "SDNT"
                        ],
                        "lista": "SDN",
                        "esAlias": false,
                        "observaciones": "DOB 23 Nov 1943; Cedula No. 1020304050 (Colombia).",
                        "documentos": [
                          "Cedula 1020304050"
                        ],
                        "fechasNacimiento": [
                          "23 Nov 1943"
                        ],
                        "coincidencia": 1
                      }
                    ],
                    "listaActualizada": "2026-07-24T15:04:05.000Z"
                  },
                  "mode": "live",
                  "fetchedAt": "2026-07-24T15:04:05.000Z",
                  "cost": 1
                }
              }
            }
          },
          "400": {
            "description": "Cuerpo inválido: placa o documento con formato incorrecto (code: bad_request)."
          },
          "401": {
            "description": "No autenticado o API key inválida (code: unauthorized)."
          },
          "402": {
            "description": "Sin créditos suficientes (code: no_credits)."
          },
          "404": {
            "description": "La fuente oficial respondió y no hay datos para la consulta. No reintentar: el resultado sería el mismo. code: propietario_no_coincide (el documento no es de un propietario activo del vehículo), vehiculo_no_registrado (el vehículo no tiene información registrada) o consulta_sin_resultado. Cada uno de esos códigos trae 10 consultas sin resultado gratis por mes y cuenta, con cuotas independientes; a partir de la 11 de ese código cobra como una consulta normal. Repetir una que ya salió sin resultado no cobra nunca (se responde de caché con fromCache: true). El body trae charged (si esta consulta cobró) y freeNoResultsLeft (cuántas gratis quedan en el mes para ESE código)."
          },
          "429": {
            "description": "Rate limit excedido: 1000 consultas/minuto por API key (code: rate_limited). Respeta Retry-After."
          },
          "500": {
            "description": "Error interno (code: internal_error)."
          },
          "502": {
            "description": "La fuente oficial no respondió a tiempo (code: source_error). Reintentar más tarde. No se cobra crédito."
          }
        }
      }
    },
    "/notificaciones-internacionales": {
      "post": {
        "operationId": "notificaciones-internacionales",
        "summary": "Notificaciones rojas (INTERPOL)",
        "description": "Notificaciones rojas públicas de INTERPOL por nombre. Nombres y apellidos van SEPARADOS porque la fuente los filtra por campos distintos; mandarlo todo junto en uno solo no encuentra nada. Devuelve cada notificación con su identificador oficial, fecha de nacimiento, nacionalidades y el enlace a la ficha pública. Cuesta 1 crédito. **Hoy responde 503 `fuente_no_disponible` y no cobra**: la fuente rechaza todas nuestras salidas de red y queda pendiente habilitar una que acepte. Costo: 1 crédito por consulta con datos.",
        "x-credits": 1,
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [],
                "properties": {
                  "nombres": {
                    "type": "string",
                    "example": "JUAN",
                    "description": "Nombres de pila. Se requiere al menos uno de `nombres` o `apellidos`."
                  },
                  "apellidos": {
                    "type": "string",
                    "example": "PEREZ GOMEZ",
                    "description": "Apellidos. Se requiere al menos uno de `nombres` o `apellidos`."
                  },
                  "refresh": {
                    "type": "boolean",
                    "example": false,
                    "description": "Ignora la caché y vuelve a consultar la fuente oficial. Ojo: una consulta refrescada con datos siempre cobra (el hit de caché no)."
                  }
                }
              },
              "example": {
                "nombres": "JUAN",
                "apellidos": "PEREZ GOMEZ"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Consulta ejecutada. Cada fuente reporta su propio status (ok, empty, error).",
            "content": {
              "application/json": {
                "example": {
                  "source": "notificaciones-internacionales",
                  "status": "danger",
                  "data": {
                    "nombreConsultado": "JUAN PEREZ GOMEZ",
                    "tieneAntecedentes": true,
                    "descripcion": "Coincide con 1 notificación(es) roja(s) publicada(s)",
                    "tieneNotificacion": true,
                    "totalCoincidencias": 1,
                    "notificaciones": [
                      {
                        "id": "2025/81694",
                        "nombres": "JUAN",
                        "apellidos": "PEREZ GOMEZ",
                        "fechaNacimiento": "1985/03/14",
                        "nacionalidades": [
                          "CO"
                        ],
                        "fichaUrl": "https://www.interpol.int/en/How-we-work/Notices/Red-Notices/View-Red-Notices#2025-81694"
                      }
                    ]
                  },
                  "mode": "live",
                  "fetchedAt": "2026-07-24T15:04:05.000Z",
                  "cost": 1
                }
              }
            }
          },
          "400": {
            "description": "Cuerpo inválido: placa o documento con formato incorrecto (code: bad_request)."
          },
          "401": {
            "description": "No autenticado o API key inválida (code: unauthorized)."
          },
          "402": {
            "description": "Sin créditos suficientes (code: no_credits)."
          },
          "404": {
            "description": "La fuente oficial respondió y no hay datos para la consulta. No reintentar: el resultado sería el mismo. code: propietario_no_coincide (el documento no es de un propietario activo del vehículo), vehiculo_no_registrado (el vehículo no tiene información registrada) o consulta_sin_resultado. Cada uno de esos códigos trae 10 consultas sin resultado gratis por mes y cuenta, con cuotas independientes; a partir de la 11 de ese código cobra como una consulta normal. Repetir una que ya salió sin resultado no cobra nunca (se responde de caché con fromCache: true). El body trae charged (si esta consulta cobró) y freeNoResultsLeft (cuántas gratis quedan en el mes para ESE código)."
          },
          "429": {
            "description": "Rate limit excedido: 1000 consultas/minuto por API key (code: rate_limited). Respeta Retry-After."
          },
          "500": {
            "description": "Error interno (code: internal_error)."
          },
          "502": {
            "description": "La fuente oficial no respondió a tiempo (code: source_error). Reintentar más tarde. No se cobra crédito."
          }
        }
      }
    },
    "/secop": {
      "post": {
        "operationId": "secop",
        "summary": "Contratación estatal (SECOP II)",
        "description": "Contratos de una persona o una empresa con el Estado colombiano, del SECOP II de Colombia Compra Eficiente. Se busca por `documento` (NIT o cédula) o por `nombre` del proveedor; el documento manda si llegan los dos. Devuelve un **resumen agregado sobre el histórico completo** —total de contratos, valor contratado, valor pagado, entidades distintas y conteo por estado— y una página de hasta 50 contratos con entidad, objeto, modalidad, valores y fechas. Es la respuesta a \"¿este proveedor ya le ha contratado al Estado, a quién y por cuánto?\", el dato que se pide en una debida diligencia. **Sin contratos también responde 200 con datos y cobra**: \"no ha contratado con el Estado\" es exactamente lo que se vino a comprobar. Cuesta 1 crédito. Costo: 1 crédito por consulta con datos.",
        "x-credits": 1,
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [],
                "properties": {
                  "documento": {
                    "type": "string",
                    "example": "900123456",
                    "description": "NIT o cédula del proveedor, solo dígitos y sin el dígito de verificación. Se requiere `documento` o `nombre`; si llegan los dos manda este, que identifica sin ambigüedad. Alias aceptados: `doc` y `nit`."
                  },
                  "nombre": {
                    "type": "string",
                    "example": "ECOPETROL",
                    "description": "Nombre o razón social del proveedor, o parte de ella (búsqueda parcial, sin distinguir mayúsculas). Útil cuando no se tiene el NIT. Mínimo 3 caracteres."
                  },
                  "estado": {
                    "type": "string",
                    "example": "En ejecución",
                    "description": "Filtra por el estado del contrato tal como lo publica la fuente: `En ejecución`, `Terminado`, `Cerrado`, `Cancelado`, `Modificado`. Sin este parámetro vienen todos."
                  },
                  "offset": {
                    "type": "number",
                    "example": 0,
                    "description": "Paginación en filas, no en número de página (0, 50, 100…). Cada página trae hasta 50 contratos; `paginacion.hayMas` dice si vale la pena pedir la siguiente."
                  },
                  "refresh": {
                    "type": "boolean",
                    "example": false,
                    "description": "Ignora la caché y vuelve a consultar la fuente oficial. Ojo: una consulta refrescada con datos siempre cobra (el hit de caché no)."
                  }
                }
              },
              "example": {
                "documento": "900123456"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Consulta ejecutada. Cada fuente reporta su propio status (ok, empty, error).",
            "content": {
              "application/json": {
                "example": {
                  "source": "contratacion-estatal",
                  "status": "info",
                  "data": {
                    "proveedor": {
                      "nombre": "CONSTRUCTORA EJEMPLO S.A.S.",
                      "documento": "900123456",
                      "tipoDocumento": "NIT"
                    },
                    "resumen": {
                      "tieneContratos": true,
                      "totalContratos": 21,
                      "valorTotal": 491032542,
                      "valorPagado": 305118000,
                      "totalEntidades": 4,
                      "porEstado": {
                        "En ejecución": 3,
                        "Terminado": 18
                      },
                      "primerContrato": "2019-04-02",
                      "ultimoContrato": "2026-06-18"
                    },
                    "contratos": [
                      {
                        "id": "CO1.PCCNTR.4168447",
                        "referencia": "CPS-3548-2022",
                        "entidad": "GOBERNACIÓN DEL QUINDÍO",
                        "nitEntidad": "890000464",
                        "objeto": "Prestación de servicios profesionales para la interventoría de la obra",
                        "tipoContrato": "Prestación de servicios",
                        "modalidad": "Contratación directa",
                        "estado": "En ejecución",
                        "valorContrato": 16000000,
                        "valorPagado": 8000000,
                        "valorPendiente": 8000000,
                        "fechaFirma": "2026-02-01",
                        "fechaInicio": "2026-02-05",
                        "fechaFin": "2026-12-31",
                        "departamento": "Quindío",
                        "ciudad": "Armenia",
                        "urlProceso": "https://community.secop.gov.co/Public/Tendering/OpportunityDetail/Index?noticeUID=CO1.NTC.0000"
                      }
                    ],
                    "paginacion": {
                      "offset": 0,
                      "limit": 50,
                      "hayMas": false
                    }
                  },
                  "mode": "live",
                  "fetchedAt": "2026-07-24T15:04:05.000Z",
                  "cost": 1
                }
              }
            }
          },
          "400": {
            "description": "Cuerpo inválido: placa o documento con formato incorrecto (code: bad_request)."
          },
          "401": {
            "description": "No autenticado o API key inválida (code: unauthorized)."
          },
          "402": {
            "description": "Sin créditos suficientes (code: no_credits)."
          },
          "404": {
            "description": "La fuente oficial respondió y no hay datos para la consulta. No reintentar: el resultado sería el mismo. code: propietario_no_coincide (el documento no es de un propietario activo del vehículo), vehiculo_no_registrado (el vehículo no tiene información registrada) o consulta_sin_resultado. Cada uno de esos códigos trae 10 consultas sin resultado gratis por mes y cuenta, con cuotas independientes; a partir de la 11 de ese código cobra como una consulta normal. Repetir una que ya salió sin resultado no cobra nunca (se responde de caché con fromCache: true). El body trae charged (si esta consulta cobró) y freeNoResultsLeft (cuántas gratis quedan en el mes para ESE código)."
          },
          "429": {
            "description": "Rate limit excedido: 1000 consultas/minuto por API key (code: rate_limited). Respeta Retry-After."
          },
          "500": {
            "description": "Error interno (code: internal_error)."
          },
          "502": {
            "description": "La fuente oficial no respondió a tiempo (code: source_error). Reintentar más tarde. No se cobra crédito."
          }
        }
      }
    },
    "/rama-judicial": {
      "post": {
        "operationId": "rama-judicial",
        "summary": "Procesos judiciales",
        "description": "Procesos judiciales de la Consulta de Procesos Nacional Unificada de la Rama Judicial. Se busca por `radicado` (23 dígitos) o por `nombre` de una de las partes, indicando si es persona natural o jurídica. Devuelve despacho, departamento, fechas y las **partes procesales ya separadas por rol** (la fuente las entrega en un solo texto plano). Consultando por radicado agrega además el **detalle** (ponente, tipo y clase de proceso, ubicación del expediente) y las **últimas actuaciones con su anotación**, que es lo que responde \"en qué va el proceso\" y no solo \"existe\". `status` es siempre `info` cuando hay procesos, nunca `danger`: la lista incluye tutelas, casos cerrados y procesos donde la persona es la DEMANDANTE. Cuesta 1 crédito. Por nombre, cero procesos es un resultado válido y cobra; un radicado que no existe responde 404 y **no cobra**. Costo: 1 crédito por consulta con datos.",
        "x-credits": 1,
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [],
                "properties": {
                  "radicado": {
                    "type": "string",
                    "example": "11001310300320210012300",
                    "description": "Número de radicado, exactamente 23 dígitos (CCCJJJSSAAAA00000000D: ciudad, juzgado, especialidad, año, consecutivo y dígito de verificación). Los guiones y espacios se ignoran. Se requiere `radicado` o `nombre`. Alias aceptado: `numero`."
                  },
                  "nombre": {
                    "type": "string",
                    "example": "CONSTRUCTORA LAS GALIAS S. A.",
                    "description": "Nombre o razón social de una de las partes. Mínimo 3 caracteres. Si la búsqueda arroja más de mil procesos la fuente la rechaza con 400 `consulta_invalida`: hay que acotarla. Alias aceptado: `razonSocial`."
                  },
                  "tipoPersona": {
                    "type": "string",
                    "example": "jur",
                    "description": "Solo aplica con `nombre`: `nat` (natural) o `jur` (jurídica). Por defecto `nat`. La fuente NO busca en las dos a la vez — pedir una empresa como `nat` devuelve vacío en silencio, que se lee como \"no tiene procesos\".",
                    "enum": [
                      "nat",
                      "jur"
                    ]
                  },
                  "soloActivos": {
                    "type": "boolean",
                    "example": false,
                    "description": "`true` deja solo los procesos activos. Por defecto vienen todos, incluidos los terminados: un proceso cerrado hace dos años sigue siendo información para quien verifica."
                  },
                  "pagina": {
                    "type": "number",
                    "example": 1,
                    "description": "Página de resultados, empezando en 1. La fuente devuelve 20 procesos por página; `paginacion.cantidadPaginas` dice cuántas hay."
                  },
                  "refresh": {
                    "type": "boolean",
                    "example": false,
                    "description": "Ignora la caché y vuelve a consultar la fuente oficial. Ojo: una consulta refrescada con datos siempre cobra (el hit de caché no)."
                  }
                }
              },
              "example": {
                "radicado": "11001310300320210012300"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Consulta ejecutada. Cada fuente reporta su propio status (ok, empty, error).",
            "content": {
              "application/json": {
                "example": {
                  "source": "procesos-judiciales",
                  "status": "info",
                  "data": {
                    "consulta": {
                      "radicado": "11001310300320210012300",
                      "nombre": "",
                      "tipoPersona": ""
                    },
                    "resumen": {
                      "tieneProcesos": true,
                      "totalProcesos": 1
                    },
                    "procesos": [
                      {
                        "idProceso": 89834312,
                        "radicado": "11001310300320210012300",
                        "fechaRadicacion": "2021-03-25",
                        "fechaUltimaActuacion": "2021-04-12",
                        "despacho": "JUZGADO 003 CIVIL DEL CIRCUITO DE BOGOTÁ",
                        "departamento": "BOGOTÁ",
                        "esPrivado": false,
                        "partes": [
                          {
                            "rol": "Demandante",
                            "nombre": "JUAN PEREZ GOMEZ"
                          },
                          {
                            "rol": "Demandado",
                            "nombre": "ENTIDAD PUBLICA DE EJEMPLO"
                          }
                        ],
                        "detalle": {
                          "ponente": "NOMBRE DEL PONENTE",
                          "tipoProceso": "Acción de Tutela",
                          "claseProceso": "Tutelas",
                          "subclaseProceso": "Sin Subclase de Proceso",
                          "recurso": "Sin Tipo de Recurso",
                          "ubicacion": "Secretaria - Oficios",
                          "ultimaActualizacion": "2026-08-19T18:33:50.517"
                        },
                        "actuaciones": [
                          {
                            "fecha": "2021-04-12",
                            "actuacion": "Sentencia tutela primera Instancia",
                            "anotacion": "CONCEDE",
                            "fechaInicial": "",
                            "fechaFinal": "",
                            "fechaRegistro": "2021-04-12",
                            "tieneDocumentos": false
                          }
                        ],
                        "totalActuaciones": 7
                      }
                    ],
                    "paginacion": {
                      "pagina": 1,
                      "registrosPagina": 20,
                      "cantidadPaginas": 1,
                      "cantidadRegistros": 1
                    }
                  },
                  "mode": "live",
                  "fetchedAt": "2026-07-24T15:04:05.000Z",
                  "cost": 1
                }
              }
            }
          },
          "400": {
            "description": "Cuerpo inválido: placa o documento con formato incorrecto (code: bad_request)."
          },
          "401": {
            "description": "No autenticado o API key inválida (code: unauthorized)."
          },
          "402": {
            "description": "Sin créditos suficientes (code: no_credits)."
          },
          "404": {
            "description": "La fuente oficial respondió y no hay datos para la consulta. No reintentar: el resultado sería el mismo. code: propietario_no_coincide (el documento no es de un propietario activo del vehículo), vehiculo_no_registrado (el vehículo no tiene información registrada) o consulta_sin_resultado. Cada uno de esos códigos trae 10 consultas sin resultado gratis por mes y cuenta, con cuotas independientes; a partir de la 11 de ese código cobra como una consulta normal. Repetir una que ya salió sin resultado no cobra nunca (se responde de caché con fromCache: true). El body trae charged (si esta consulta cobró) y freeNoResultsLeft (cuántas gratis quedan en el mes para ESE código)."
          },
          "429": {
            "description": "Rate limit excedido: 1000 consultas/minuto por API key (code: rate_limited). Respeta Retry-After."
          },
          "500": {
            "description": "Error interno (code: internal_error)."
          },
          "502": {
            "description": "La fuente oficial no respondió a tiempo (code: source_error). Reintentar más tarde. No se cobra crédito."
          }
        }
      }
    },
    "/sigep": {
      "post": {
        "operationId": "sigep",
        "summary": "Declaraciones de bienes y rentas",
        "description": "Declaraciones de bienes y rentas y conflicto de interés (Ley 2013 de 2019) de servidores públicos y contratistas del Estado, del buscador ciudadano de la Función Pública. Se busca por `documento` o por `nombre`. Devuelve cada declaración con la entidad, el cargo, el motivo (ingreso, periódico o retiro), el número, la fecha de publicación y su estado, más un resumen con las entidades donde ha declarado. Responde \"¿esta persona de verdad trabaja o contrata con el Estado, dónde y desde cuándo?\". **No entrega el PDF de la declaración**: la descarga del portal sí valida captcha y no se puede automatizar; se devuelve `idDeclaracion` y `portalUrl` para bajarlo a mano. Cuesta 1 crédito, y \"no tiene declaraciones publicadas\" es una respuesta válida que cobra. Costo: 1 crédito por consulta con datos.",
        "x-credits": 1,
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [],
                "properties": {
                  "documento": {
                    "type": "string",
                    "example": "1020304050",
                    "description": "Número de documento del declarante. Se requiere `documento` o `nombre`. Alias aceptados: `doc` y `cedula`."
                  },
                  "nombre": {
                    "type": "string",
                    "example": "MARIA FERNANDA GOMEZ",
                    "description": "Nombre del declarante, o parte de él (búsqueda parcial). Mínimo 3 caracteres."
                  },
                  "tipoPersona": {
                    "type": "string",
                    "example": "nat",
                    "description": "`nat` (natural, por defecto) o `jur` (jurídica). La fuente consulta las dos por separado y NO busca en ambas a la vez.",
                    "enum": [
                      "nat",
                      "jur"
                    ]
                  },
                  "refresh": {
                    "type": "boolean",
                    "example": false,
                    "description": "Ignora la caché y vuelve a consultar la fuente oficial. Ojo: una consulta refrescada con datos siempre cobra (el hit de caché no)."
                  }
                }
              },
              "example": {
                "documento": "1020304050"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Consulta ejecutada. Cada fuente reporta su propio status (ok, empty, error).",
            "content": {
              "application/json": {
                "example": {
                  "source": "declaraciones-bienes-rentas",
                  "status": "info",
                  "data": {
                    "consulta": {
                      "documento": "1020304050",
                      "nombre": ""
                    },
                    "resumen": {
                      "tieneDeclaraciones": true,
                      "totalDeclaraciones": 2,
                      "entidades": [
                        "ALCALDIA DE MUNICIPIO EJEMPLO"
                      ],
                      "ultimaPublicacion": "2026-07-10 12:07"
                    },
                    "declaraciones": [
                      {
                        "idDeclaracion": "9000001",
                        "nombre": "MARIA FERNANDA GOMEZ RUIZ",
                        "tipoDocumento": "CEDULA DE CIUDADANIA",
                        "numeroDocumento": "1020304050",
                        "entidad": "ALCALDIA DE MUNICIPIO EJEMPLO",
                        "cargo": "CONTRATISTA",
                        "tipoPublicacion": "PERIÓDICO",
                        "declaracionNo": "8100001-02",
                        "observacion": "Corrección de 8100001-01",
                        "fechaPublicacion": "2026-07-10 12:07",
                        "estado": "FINALIZADO"
                      }
                    ],
                    "portalUrl": "https://www.funcionpublica.gov.co/fdci/consultaCiudadana"
                  },
                  "mode": "live",
                  "fetchedAt": "2026-07-24T15:04:05.000Z",
                  "cost": 1
                }
              }
            }
          },
          "400": {
            "description": "Cuerpo inválido: placa o documento con formato incorrecto (code: bad_request)."
          },
          "401": {
            "description": "No autenticado o API key inválida (code: unauthorized)."
          },
          "402": {
            "description": "Sin créditos suficientes (code: no_credits)."
          },
          "404": {
            "description": "La fuente oficial respondió y no hay datos para la consulta. No reintentar: el resultado sería el mismo. code: propietario_no_coincide (el documento no es de un propietario activo del vehículo), vehiculo_no_registrado (el vehículo no tiene información registrada) o consulta_sin_resultado. Cada uno de esos códigos trae 10 consultas sin resultado gratis por mes y cuenta, con cuotas independientes; a partir de la 11 de ese código cobra como una consulta normal. Repetir una que ya salió sin resultado no cobra nunca (se responde de caché con fromCache: true). El body trae charged (si esta consulta cobró) y freeNoResultsLeft (cuántas gratis quedan en el mes para ESE código)."
          },
          "429": {
            "description": "Rate limit excedido: 1000 consultas/minuto por API key (code: rate_limited). Respeta Retry-After."
          },
          "500": {
            "description": "Error interno (code: internal_error)."
          },
          "502": {
            "description": "La fuente oficial no respondió a tiempo (code: source_error). Reintentar más tarde. No se cobra crédito."
          }
        }
      }
    },
    "/rues": {
      "post": {
        "operationId": "rues",
        "summary": "Registro mercantil",
        "description": "Empresas y comerciantes inscritos en las Cámaras de Comercio (el registro que el público consulta como \"RUES\"). Se busca por `documento` (NIT o cédula, vía exacta y recomendada) o por `nombre`. Devuelve razón social, matrícula, cámara, **estado de la matrícula**, tipo de sociedad, organización jurídica, códigos CIIU principal y secundario, fechas de matrícula, renovación, vigencia y cancelación, el último año renovado, si está inscrita como proponente y el **representante legal con su documento**. La búsqueda por `nombre` es de **texto completo**: \"EL OSO\" encuentra también \"INVERSIONES ALTAMIRA EL OSO\", y los resultados llegan por relevancia. `resumen.totalCoincidencias` es el conteo real en las dos vías. Cuesta 1 crédito, y cero coincidencias es un resultado válido que cobra. Costo: 1 crédito por consulta con datos.",
        "x-credits": 1,
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [],
                "properties": {
                  "documento": {
                    "type": "string",
                    "example": "899999068",
                    "description": "NIT o cédula del inscrito. Se acepta con puntos y con el dígito de verificación (`900123456-7`): se normaliza y el dígito se descarta, porque el registro lo guarda en una columna aparte y buscarlo pegado no encuentra nada. Alias aceptados: `doc`, `nit`."
                  },
                  "nombre": {
                    "type": "string",
                    "example": "ECOPETROL",
                    "description": "Razón social o cualquier parte de ella: es búsqueda de texto completo, no por prefijo. Mínimo 3 caracteres. Alias aceptado: `razonSocial`."
                  },
                  "termino": {
                    "type": "string",
                    "example": "ECOPETROL",
                    "description": "Campo único que acepta NIT **o** razón social; se enruta según su contenido (solo dígitos = documento). Existe para migrar desde proveedores que usan un solo campo de búsqueda."
                  },
                  "offset": {
                    "type": "number",
                    "example": 0,
                    "description": "Paginación en filas (0, 50, 100…). Cada página trae hasta 50 registros."
                  },
                  "refresh": {
                    "type": "boolean",
                    "example": false,
                    "description": "Ignora la caché y vuelve a consultar la fuente oficial. Ojo: una consulta refrescada con datos siempre cobra (el hit de caché no)."
                  }
                }
              },
              "example": {
                "documento": "899999068"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Consulta ejecutada. Cada fuente reporta su propio status (ok, empty, error).",
            "content": {
              "application/json": {
                "example": {
                  "source": "registro-mercantil",
                  "status": "info",
                  "data": {
                    "consulta": {
                      "documento": "899999068",
                      "nombre": ""
                    },
                    "resumen": {
                      "tieneRegistro": true,
                      "totalCoincidencias": 1,
                      "exacto": true,
                      "activas": 1
                    },
                    "empresas": [
                      {
                        "razonSocial": "EMPRESA DE EJEMPLO S A",
                        "numeroIdentificacion": "899999068",
                        "claseIdentificacion": "NIT",
                        "digitoVerificacion": "1",
                        "matricula": "1291197",
                        "camaraComercio": "BOGOTA",
                        "estadoMatricula": "ACTIVA",
                        "tipoSociedad": "SOCIEDAD COMERCIAL",
                        "organizacionJuridica": "SOCIEDAD ANONIMA",
                        "categoriaMatricula": "SOCIEDAD ó PERSONA JURIDICA PRINCIPAL ó ESAL",
                        "ciiuPrincipal": "0610",
                        "ciiuSecundario": "0620",
                        "fechaMatricula": "2003-07-18",
                        "fechaRenovacion": "2026-03-30",
                        "fechaCancelacion": "",
                        "fechaVigencia": "2103-07-07",
                        "ultimoAnoRenovado": "2026",
                        "representanteLegal": "NOMBRE DEL REPRESENTANTE LEGAL",
                        "documentoRepresentanteLegal": "19451246",
                        "inscritaComoProponente": false
                      }
                    ],
                    "paginacion": {
                      "offset": 0,
                      "limit": 50,
                      "hayMas": false
                    }
                  },
                  "mode": "live",
                  "fetchedAt": "2026-07-24T15:04:05.000Z",
                  "cost": 1
                }
              }
            }
          },
          "400": {
            "description": "Cuerpo inválido: placa o documento con formato incorrecto (code: bad_request)."
          },
          "401": {
            "description": "No autenticado o API key inválida (code: unauthorized)."
          },
          "402": {
            "description": "Sin créditos suficientes (code: no_credits)."
          },
          "404": {
            "description": "La fuente oficial respondió y no hay datos para la consulta. No reintentar: el resultado sería el mismo. code: propietario_no_coincide (el documento no es de un propietario activo del vehículo), vehiculo_no_registrado (el vehículo no tiene información registrada) o consulta_sin_resultado. Cada uno de esos códigos trae 10 consultas sin resultado gratis por mes y cuenta, con cuotas independientes; a partir de la 11 de ese código cobra como una consulta normal. Repetir una que ya salió sin resultado no cobra nunca (se responde de caché con fromCache: true). El body trae charged (si esta consulta cobró) y freeNoResultsLeft (cuántas gratis quedan en el mes para ESE código)."
          },
          "429": {
            "description": "Rate limit excedido: 1000 consultas/minuto por API key (code: rate_limited). Respeta Retry-After."
          },
          "500": {
            "description": "Error interno (code: internal_error)."
          },
          "502": {
            "description": "La fuente oficial no respondió a tiempo (code: source_error). Reintentar más tarde. No se cobra crédito."
          }
        }
      }
    },
    "/cedula": {
      "post": {
        "operationId": "cedula",
        "summary": "Nombre por documento",
        "description": "Nombre completo del titular de un documento de identidad. Devuelve el nombre ya partido en `partes`, para no tener que adivinar del lado del cliente dónde termina el nombre y empieza el apellido. Consulta DOS registros en cascada: primero el registro social del DNP —instantáneo, y de regalo trae `sexo`, `edad`, `municipio` y `departamento`—, y si la persona no figura ahí cae al certificado de la Procuraduría, que cubre a cualquiera con documento colombiano pero tarda más. `origen` dice cuál respondió, así se sabe por qué unos campos vienen vacíos. Es el primer paso de cualquier verificación: confirmar que el documento existe y a quién pertenece antes de gastar consultas en antecedentes o en el vehículo. **Un documento sin titular registrado responde 404 y NO cobra** — a diferencia de los antecedentes, donde \"no registra\" sí cobra: acá el producto es el nombre, y si no vino no se entregó nada. Cuesta 1 crédito. Costo: 1 crédito por consulta con datos.",
        "x-credits": 1,
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "docType",
                  "docNumber"
                ],
                "properties": {
                  "docType": {
                    "type": "string",
                    "example": "CC",
                    "description": "Tipo de documento. La cobertura depende de cuál de los dos registros responda: el social maneja RC, TI, CC, CE, PA, PEP y PPT; el certificado maneja CC, CE, NIT, PPT y PEP. Un tipo que ninguno acepta responde 400 `tipo_documento_no_soportado` sin cobrar.",
                    "enum": [
                      "CC",
                      "CE",
                      "TI",
                      "RC",
                      "PA",
                      "NIT",
                      "PPT",
                      "PEP"
                    ]
                  },
                  "docNumber": {
                    "type": "string",
                    "example": "1020304050",
                    "description": "Número de documento. Alias aceptado: `doc`."
                  },
                  "primerNombre": {
                    "type": "string",
                    "example": "JUAN",
                    "description": "Primer nombre del titular. OPCIONAL: solo se usa si la consulta cae al certificado, donde ahorra un par de peticiones al resolver la pregunta de seguridad del portal. No cambia el resultado ni la caché."
                  },
                  "refresh": {
                    "type": "boolean",
                    "example": false,
                    "description": "Ignora la caché y vuelve a consultar la fuente oficial. Ojo: una consulta refrescada con datos siempre cobra (el hit de caché no)."
                  }
                }
              },
              "example": {
                "docType": "CC",
                "docNumber": "1020304050"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Consulta ejecutada. Cada fuente reporta su propio status (ok, empty, error).",
            "content": {
              "application/json": {
                "example": {
                  "source": "identidad",
                  "status": "info",
                  "data": {
                    "documento": "1020304050",
                    "tipoDocumento": "Cédula de ciudadanía",
                    "nombre": "JUAN CARLOS PEREZ GOMEZ",
                    "partes": [
                      "JUAN",
                      "CARLOS",
                      "PEREZ",
                      "GOMEZ"
                    ],
                    "sexo": "Masculino",
                    "edad": 38,
                    "municipio": "CALI",
                    "departamento": "VALLE DEL CAUCA",
                    "origen": "registro-social"
                  },
                  "mode": "live",
                  "fetchedAt": "2026-07-24T15:04:05.000Z",
                  "cost": 1
                }
              }
            }
          },
          "400": {
            "description": "Cuerpo inválido: placa o documento con formato incorrecto (code: bad_request)."
          },
          "401": {
            "description": "No autenticado o API key inválida (code: unauthorized)."
          },
          "402": {
            "description": "Sin créditos suficientes (code: no_credits)."
          },
          "404": {
            "description": "La fuente oficial respondió y no hay datos para la consulta. No reintentar: el resultado sería el mismo. code: propietario_no_coincide (el documento no es de un propietario activo del vehículo), vehiculo_no_registrado (el vehículo no tiene información registrada) o consulta_sin_resultado. Cada uno de esos códigos trae 10 consultas sin resultado gratis por mes y cuenta, con cuotas independientes; a partir de la 11 de ese código cobra como una consulta normal. Repetir una que ya salió sin resultado no cobra nunca (se responde de caché con fromCache: true). El body trae charged (si esta consulta cobró) y freeNoResultsLeft (cuántas gratis quedan en el mes para ESE código)."
          },
          "429": {
            "description": "Rate limit excedido: 1000 consultas/minuto por API key (code: rate_limited). Respeta Retry-After."
          },
          "500": {
            "description": "Error interno (code: internal_error)."
          },
          "502": {
            "description": "La fuente oficial no respondió a tiempo (code: source_error). Reintentar más tarde. No se cobra crédito."
          }
        }
      }
    },
    "/sisben": {
      "post": {
        "operationId": "sisben",
        "summary": "Clasificación social (Sisbén y RUI)",
        "description": "Clasificación socioeconómica de una persona por documento, de la Ventanilla Social del DNP. Devuelve el **grupo del Sisbén IV** (A pobreza extrema · B pobreza moderada · C vulnerable · D no pobre/no vulnerable) con su subgrupo y descripción, el **grupo del RUI** —el Registro Universal de Ingresos, la escala que reemplazó al Sisbén como criterio de focalización— y los datos básicos de la persona: nombre, sexo, edad, municipio y departamento. Sirve para verificar elegibilidad a subsidios y programas sociales. **Una persona no registrada responde 404 y NO cobra.** ⚠️ Nota de calidad que conviene conocer: el endpoint oficial del grupo Sisbén le asigna \"D4 – no pobre, no vulnerable\" a documentos que **no existen**; acá la existencia la decide el registro de ingresos y el grupo solo se publica si esa verificación pasó, así que un `sisben: null` significa \"la persona existe pero no tiene grupo publicado\", nunca un dato inventado. Cuesta 1 crédito. Costo: 1 crédito por consulta con datos.",
        "x-credits": 1,
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "docType",
                  "docNumber"
                ],
                "properties": {
                  "docType": {
                    "type": "string",
                    "example": "CC",
                    "description": "Tipo de documento. Es un registro de PERSONAS naturales: con NIT o carné diplomático responde 400 `tipo_documento_no_soportado` sin cobrar.",
                    "enum": [
                      "CC",
                      "CE",
                      "TI",
                      "RC",
                      "PA",
                      "PPT",
                      "PEP"
                    ]
                  },
                  "docNumber": {
                    "type": "string",
                    "example": "1020304050",
                    "description": "Número de documento. Alias aceptado: `doc`."
                  },
                  "refresh": {
                    "type": "boolean",
                    "example": false,
                    "description": "Ignora la caché y vuelve a consultar la fuente oficial. Ojo: una consulta refrescada con datos siempre cobra (el hit de caché no)."
                  }
                }
              },
              "example": {
                "docType": "CC",
                "docNumber": "1020304050"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Consulta ejecutada. Cada fuente reporta su propio status (ok, empty, error).",
            "content": {
              "application/json": {
                "example": {
                  "source": "clasificacion-social",
                  "status": "info",
                  "data": {
                    "documento": "1020304050",
                    "tipoDocumento": "CC",
                    "persona": {
                      "nombre": "JUAN CARLOS PEREZ GOMEZ",
                      "sexo": "Masculino",
                      "edad": 38
                    },
                    "ubicacion": {
                      "departamento": "VALLE DEL CAUCA",
                      "municipio": "CALI",
                      "codigoMunicipio": "76001"
                    },
                    "sisben": {
                      "grupo": "B",
                      "nivel": "B6",
                      "descripcion": "Pobreza moderada"
                    },
                    "rui": {
                      "tieneClasificacion": true,
                      "grupo": "C",
                      "nivel": "C15",
                      "grupoIngresos": "Ingreso observado y estimado"
                    }
                  },
                  "mode": "live",
                  "fetchedAt": "2026-07-24T15:04:05.000Z",
                  "cost": 1
                }
              }
            }
          },
          "400": {
            "description": "Cuerpo inválido: placa o documento con formato incorrecto (code: bad_request)."
          },
          "401": {
            "description": "No autenticado o API key inválida (code: unauthorized)."
          },
          "402": {
            "description": "Sin créditos suficientes (code: no_credits)."
          },
          "404": {
            "description": "La fuente oficial respondió y no hay datos para la consulta. No reintentar: el resultado sería el mismo. code: propietario_no_coincide (el documento no es de un propietario activo del vehículo), vehiculo_no_registrado (el vehículo no tiene información registrada) o consulta_sin_resultado. Cada uno de esos códigos trae 10 consultas sin resultado gratis por mes y cuenta, con cuotas independientes; a partir de la 11 de ese código cobra como una consulta normal. Repetir una que ya salió sin resultado no cobra nunca (se responde de caché con fromCache: true). El body trae charged (si esta consulta cobró) y freeNoResultsLeft (cuántas gratis quedan en el mes para ESE código)."
          },
          "429": {
            "description": "Rate limit excedido: 1000 consultas/minuto por API key (code: rate_limited). Respeta Retry-After."
          },
          "500": {
            "description": "Error interno (code: internal_error)."
          },
          "502": {
            "description": "La fuente oficial no respondió a tiempo (code: source_error). Reintentar más tarde. No se cobra crédito."
          }
        }
      }
    },
    "/rui": {
      "post": {
        "operationId": "rui",
        "summary": "Registro Universal de Ingresos (RUI)",
        "description": "Grupo del **Registro Universal de Ingresos (RUI)** de una persona por documento, de la Ventanilla Social del DNP: el nivel y el grupo de ingresos con los que hoy se decide el acceso a programas sociales. **Es el mismo endpoint que `/api/sisben`** y devuelve el mismo objeto —la fuente entrega las dos escalas juntas y aquí se entregan las dos—, así que da igual cuál se llame; existe con nombre propio porque el RUI reemplazó al Sisbén como criterio de focalización y quien trae una regla escrita en grupos del RUI no puede traducirla a grupos del Sisbén. Junto al RUI vienen el grupo del **Sisbén IV** y los datos básicos de la persona; el detalle de esa escala está en `/api/sisben`. **Una persona no registrada responde 404 y NO cobra.** ⚠️ La existencia del documento la decide el registro de ingresos y no el grupo del Sisbén: el endpoint oficial de ese grupo le asigna \"D4 – no pobre, no vulnerable\" a documentos que **no existen**, así que aquí un `sisben: null` significa \"la persona existe y no tiene grupo publicado\", nunca un dato inventado. Cuesta 1 crédito. Costo: 1 crédito por consulta con datos.",
        "x-credits": 1,
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "docType",
                  "docNumber"
                ],
                "properties": {
                  "docType": {
                    "type": "string",
                    "example": "CC",
                    "description": "Tipo de documento. Es un registro de PERSONAS naturales: con NIT o carné diplomático responde 400 `tipo_documento_no_soportado` sin cobrar.",
                    "enum": [
                      "CC",
                      "CE",
                      "TI",
                      "RC",
                      "PA",
                      "PPT",
                      "PEP"
                    ]
                  },
                  "docNumber": {
                    "type": "string",
                    "example": "1020304050",
                    "description": "Número de documento. Alias aceptado: `doc`."
                  },
                  "refresh": {
                    "type": "boolean",
                    "example": false,
                    "description": "Ignora la caché y vuelve a consultar la fuente oficial. Ojo: una consulta refrescada con datos siempre cobra (el hit de caché no)."
                  }
                }
              },
              "example": {
                "docType": "CC",
                "docNumber": "1020304050"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Consulta ejecutada. Cada fuente reporta su propio status (ok, empty, error).",
            "content": {
              "application/json": {
                "example": {
                  "source": "clasificacion-social",
                  "status": "info",
                  "data": {
                    "documento": "1020304050",
                    "tipoDocumento": "CC",
                    "persona": {
                      "nombre": "JUAN CARLOS PEREZ GOMEZ",
                      "sexo": "Masculino",
                      "edad": 38
                    },
                    "ubicacion": {
                      "departamento": "VALLE DEL CAUCA",
                      "municipio": "CALI",
                      "codigoMunicipio": "76001"
                    },
                    "sisben": {
                      "grupo": "B",
                      "nivel": "B6",
                      "descripcion": "Pobreza moderada"
                    },
                    "rui": {
                      "tieneClasificacion": true,
                      "grupo": "C",
                      "nivel": "C15",
                      "grupoIngresos": "Ingreso observado y estimado"
                    }
                  },
                  "mode": "live",
                  "fetchedAt": "2026-07-24T15:04:05.000Z",
                  "cost": 1
                }
              }
            }
          },
          "400": {
            "description": "Cuerpo inválido: placa o documento con formato incorrecto (code: bad_request)."
          },
          "401": {
            "description": "No autenticado o API key inválida (code: unauthorized)."
          },
          "402": {
            "description": "Sin créditos suficientes (code: no_credits)."
          },
          "404": {
            "description": "La fuente oficial respondió y no hay datos para la consulta. No reintentar: el resultado sería el mismo. code: propietario_no_coincide (el documento no es de un propietario activo del vehículo), vehiculo_no_registrado (el vehículo no tiene información registrada) o consulta_sin_resultado. Cada uno de esos códigos trae 10 consultas sin resultado gratis por mes y cuenta, con cuotas independientes; a partir de la 11 de ese código cobra como una consulta normal. Repetir una que ya salió sin resultado no cobra nunca (se responde de caché con fromCache: true). El body trae charged (si esta consulta cobró) y freeNoResultsLeft (cuántas gratis quedan en el mes para ESE código)."
          },
          "429": {
            "description": "Rate limit excedido: 1000 consultas/minuto por API key (code: rate_limited). Respeta Retry-After."
          },
          "500": {
            "description": "Error interno (code: internal_error)."
          },
          "502": {
            "description": "La fuente oficial no respondió a tiempo (code: source_error). Reintentar más tarde. No se cobra crédito."
          }
        }
      }
    },
    "/puesto-votacion": {
      "post": {
        "operationId": "puesto-votacion",
        "summary": "Puesto de votación",
        "description": "Dónde le toca votar a una persona, por cédula, del censo electoral de la Registraduría. Devuelve el **puesto** con su nombre oficial, la **dirección**, el **número de mesa**, el **municipio y departamento**, el **código DIVIPOL** del puesto —el mismo con el que la Registraduría publica logística y resultados— y las **coordenadas** del sitio con enlace de navegación, cuando la fuente lo tiene georreferenciado. Trae además `fechaInscripcion`, que es desde cuándo la persona figura en ese puesto: eso delata a quien acaba de trasladarse. **No es estacional**: consulta el lugar de votación vigente y responde también fuera de calendario electoral. Sirve para logística de transporte el día de elecciones, verificación de residencia electoral y validación de datos de afiliados. ⚠️ **Solo cédula de ciudadanía** — el censo electoral no maneja otro documento, y cualquier otro tipo responde 400 sin cobrar. **Un documento que no figura en el censo responde 404 y NO cobra**: acá el producto es el puesto, y si no vino no se entregó nada. La fuente distingue dos formas de \"no hay puesto\": que el documento no figure en el censo, y que tenga una **novedad** que lo saca de él (cédula cancelada por muerte, no expedida). Las dos responden 404 con el mensaje textual del registro y ninguna cobra: el estado de la cédula es otra pregunta, y no la vendemos como si fuera esta. Cuesta 1 crédito. Costo: 1 crédito por consulta con datos.",
        "x-credits": 1,
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "docType",
                  "docNumber"
                ],
                "properties": {
                  "docType": {
                    "type": "string",
                    "example": "CC",
                    "description": "Tipo de documento. El censo electoral es de ciudadanos colombianos y solo maneja cédula de ciudadanía: cualquier otro valor responde 400 `tipo_documento_no_soportado` sin cobrar y sin consultar a la fuente.",
                    "enum": [
                      "CC"
                    ]
                  },
                  "docNumber": {
                    "type": "string",
                    "example": "1020304050",
                    "description": "Número de cédula. Alias aceptado: `doc`."
                  },
                  "refresh": {
                    "type": "boolean",
                    "example": false,
                    "description": "Ignora la caché y vuelve a consultar la fuente oficial. Ojo: una consulta refrescada con datos siempre cobra (el hit de caché no)."
                  }
                }
              },
              "example": {
                "docType": "CC",
                "docNumber": "1020304050"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Consulta ejecutada. Cada fuente reporta su propio status (ok, empty, error).",
            "content": {
              "application/json": {
                "example": {
                  "source": "puesto-votacion",
                  "status": "info",
                  "data": {
                    "documento": "1020304050",
                    "departamento": "VALLE",
                    "municipio": "CALI",
                    "puesto": "INSTITUCION EDUCATIVA EJEMPLO",
                    "direccion": "CALLE 00 # 00-00",
                    "mesa": "24",
                    "codigoPuesto": "310019914",
                    "fechaInscripcion": "2026-02-07",
                    "ubicacion": {
                      "lat": 3.35393,
                      "lng": -76.523,
                      "mapsUrl": "https://www.google.com/maps/dir/?api=1&destination=3.35393,-76.52300"
                    }
                  },
                  "mode": "live",
                  "fetchedAt": "2026-07-24T15:04:05.000Z",
                  "cost": 1
                }
              }
            }
          },
          "400": {
            "description": "Cuerpo inválido: placa o documento con formato incorrecto (code: bad_request)."
          },
          "401": {
            "description": "No autenticado o API key inválida (code: unauthorized)."
          },
          "402": {
            "description": "Sin créditos suficientes (code: no_credits)."
          },
          "404": {
            "description": "La fuente oficial respondió y no hay datos para la consulta. No reintentar: el resultado sería el mismo. code: propietario_no_coincide (el documento no es de un propietario activo del vehículo), vehiculo_no_registrado (el vehículo no tiene información registrada) o consulta_sin_resultado. Cada uno de esos códigos trae 10 consultas sin resultado gratis por mes y cuenta, con cuotas independientes; a partir de la 11 de ese código cobra como una consulta normal. Repetir una que ya salió sin resultado no cobra nunca (se responde de caché con fromCache: true). El body trae charged (si esta consulta cobró) y freeNoResultsLeft (cuántas gratis quedan en el mes para ESE código)."
          },
          "429": {
            "description": "Rate limit excedido: 1000 consultas/minuto por API key (code: rate_limited). Respeta Retry-After."
          },
          "500": {
            "description": "Error interno (code: internal_error)."
          },
          "502": {
            "description": "La fuente oficial no respondió a tiempo (code: source_error). Reintentar más tarde. No se cobra crédito."
          }
        }
      }
    },
    "/ruaf": {
      "post": {
        "operationId": "ruaf",
        "summary": "Afiliaciones a seguridad social",
        "description": "Todas las afiliaciones de una persona al sistema de seguridad social, del RUAF del Ministerio de Salud, en UNA llamada: **salud** (EPS, régimen, tipo de afiliado y estado), **pensiones** (fondo y régimen), **riesgos laborales** (ARL), **caja de compensación**, **cesantías**, si está **pensionada** y a qué **programas de asistencia social** está vinculada. Responde \"¿esta persona está cotizando hoy, dónde y por qué régimen?\" — la pregunta de una vinculación laboral o un estudio de seguridad. Requiere la **fecha de expedición** del documento: la exige la fuente para autenticar, no nosotros. `fechaCorte` dice hasta cuándo están actualizados los datos, que NO es la fecha de la consulta: el Ministerio consolida con rezago. **Cuesta 2 créditos** — es el scrape más caro del catálogo de personas y sustituye a siete consultas. ⏱️ **Es también el más lento: cuenta con decenas de segundos**, porque el informe lo genera un visor de reportes del Ministerio que no se puede apurar; conviene llamarlo de forma asíncrona y no dentro de una petición web con el usuario esperando. Una fecha que no coincide responde 404 y no cobra. Costo: 2 créditos por consulta con datos.",
        "x-credits": 2,
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "docNumber",
                  "fechaExpedicion"
                ],
                "properties": {
                  "docType": {
                    "type": "string",
                    "example": "CC",
                    "description": "Tipo de documento. Por defecto `CC`. Con NIT responde 400 `tipo_documento_no_soportado`: el RUAF es un registro de personas naturales.",
                    "enum": [
                      "CC",
                      "CE",
                      "TI",
                      "RC",
                      "PA",
                      "PPT",
                      "PEP"
                    ]
                  },
                  "docNumber": {
                    "type": "string",
                    "example": "1020304050",
                    "description": "Número de documento. Alias aceptados: `doc`, `documento`."
                  },
                  "fechaExpedicion": {
                    "type": "string",
                    "example": "05/10/2018",
                    "description": "Fecha de expedición del documento en formato **DD/MM/AAAA**. Se aceptan guiones y puntos como separador y se normalizan. NO se acepta AAAA-MM-DD: la fuente lo leería al revés y respondería \"no coincide\" sin explicar por qué. Alias aceptados: `fecha`, `fecha_expedicion`."
                  },
                  "refresh": {
                    "type": "boolean",
                    "example": false,
                    "description": "Ignora la caché y vuelve a consultar la fuente oficial. Ojo: una consulta refrescada con datos siempre cobra (el hit de caché no)."
                  }
                }
              },
              "example": {
                "docType": "CC",
                "docNumber": "1020304050",
                "fechaExpedicion": "05/10/2018"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Consulta ejecutada. Cada fuente reporta su propio status (ok, empty, error).",
            "content": {
              "application/json": {
                "example": {
                  "source": "afiliaciones-seguridad-social",
                  "status": "info",
                  "data": {
                    "documento": "1020304050",
                    "tipoDocumento": "CC",
                    "fechaCorte": "2026-08-14",
                    "persona": {
                      "nombre": "MARIA FERNANDA GOMEZ RUIZ",
                      "primerNombre": "MARIA",
                      "segundoNombre": "FERNANDA",
                      "primerApellido": "GOMEZ",
                      "segundoApellido": "RUIZ",
                      "sexo": "F"
                    },
                    "salud": {
                      "tiene": true,
                      "registros": [
                        {
                          "administradora": "NUEVA EPS S.A.",
                          "regimen": "Contributivo",
                          "fechaAfiliacion": "01/11/2024",
                          "estado": "Activo",
                          "tipoAfiliado": "COTIZANTE",
                          "ubicacion": "SANTIAGO DE CALI",
                          "actividadEconomica": "",
                          "tipoMiembro": ""
                        }
                      ]
                    },
                    "pensiones": {
                      "tiene": true,
                      "registros": [
                        {
                          "administradora": "FONDO DE PENSIONES DE EJEMPLO S.A.",
                          "regimen": "PENSIONES: AHORRO INDIVIDUAL",
                          "fechaAfiliacion": "2022-09-06",
                          "estado": "Inactivo",
                          "tipoAfiliado": "",
                          "ubicacion": "",
                          "actividadEconomica": "",
                          "tipoMiembro": ""
                        }
                      ]
                    },
                    "riesgosLaborales": {
                      "tiene": true,
                      "registros": []
                    },
                    "compensacionFamiliar": {
                      "tiene": true,
                      "registros": []
                    },
                    "cesantias": {
                      "tiene": true,
                      "registros": []
                    },
                    "pensionado": {
                      "tiene": false,
                      "registros": []
                    },
                    "asistenciaSocial": {
                      "tiene": true,
                      "registros": [
                        {
                          "administradora": "DEPARTAMENTO PARA LA PROSPERIDAD SOCIAL",
                          "programa": "Jovenes en Acción",
                          "fechaVinculacion": "2020-09-03",
                          "estadoVinculacion": "Activo",
                          "estadoBeneficio": "Terminado",
                          "fechaUltimoBeneficio": "2021-10-29",
                          "ubicacion": "Risaralda- PEREIRA"
                        }
                      ]
                    }
                  },
                  "mode": "live",
                  "fetchedAt": "2026-07-24T15:04:05.000Z",
                  "cost": 2
                }
              }
            }
          },
          "400": {
            "description": "Cuerpo inválido: placa o documento con formato incorrecto (code: bad_request)."
          },
          "401": {
            "description": "No autenticado o API key inválida (code: unauthorized)."
          },
          "402": {
            "description": "Sin créditos suficientes (code: no_credits)."
          },
          "404": {
            "description": "La fuente oficial respondió y no hay datos para la consulta. No reintentar: el resultado sería el mismo. code: propietario_no_coincide (el documento no es de un propietario activo del vehículo), vehiculo_no_registrado (el vehículo no tiene información registrada) o consulta_sin_resultado. Cada uno de esos códigos trae 10 consultas sin resultado gratis por mes y cuenta, con cuotas independientes; a partir de la 11 de ese código cobra como una consulta normal. Repetir una que ya salió sin resultado no cobra nunca (se responde de caché con fromCache: true). El body trae charged (si esta consulta cobró) y freeNoResultsLeft (cuántas gratis quedan en el mes para ESE código)."
          },
          "429": {
            "description": "Rate limit excedido: 1000 consultas/minuto por API key (code: rate_limited). Respeta Retry-After."
          },
          "500": {
            "description": "Error interno (code: internal_error)."
          },
          "502": {
            "description": "La fuente oficial no respondió a tiempo (code: source_error). Reintentar más tarde. No se cobra crédito."
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "x-api-key"
      }
    }
  },
  "security": [
    {
      "ApiKeyAuth": []
    }
  ]
}