🇵🇪 Perú · fuente pública
OECE/SEACE: tenders
Licitaciones y contratos del sector público peruano — procedimientos de selección, adjudicaciones, contratos firmados. Incluye monto, entidad compradora, proveedor adjudicado, método de selección, fechas y descripción del objeto.
Cobertura publicada
- Registros
- 2,408,723
- Última actualización
- 26 set. 2026
- Frecuencia
- daily
- Frescura
- CURRENT
- Identificador
ocid- Búsqueda por nombre
- Disponible
Conteo y frescura consultados desde api.latinfo.dev/sources durante el build del 2026-09-28.
Fuente primaria
- Institution: OECE — Organismo Especializado para las Contrataciones Públicas Eficientes (antes OSCE). Publica SEACE bajo el estándar OCDS (Open Contracting Data Standard).
- Data: Licitaciones y contratos del sector público peruano — procedimientos de selección, adjudicaciones, contratos firmados. Incluye monto, entidad compradora, proveedor adjudicado, método de selección, fechas y descripción del objeto.
- Format: ZIP que contiene JSON (record package OCDS 1.1), 1 archivo por mes.
- Registered: https://www.datosabiertos.gob.pe/dataset/contrataciones-p%C3%BAblicas-del-estado-peruano-organismo-especializado-para-las
Cómo se procesa
- Dos sistemas, mismo host, OCIDs que no colisionan:
seace_v2: 2005-01 → 2013-01 (SEACE legacy). OCID prefixocds-dgv273-seacev2-*.seace_v3: 2013-02 → presente (SEACE reprocessed). OCID prefixocds-dgv273-seacev3-*.
- Modos:
--current(default): descarga el mes en curso, reemplaza shard.--all: histórico completo desde 2005-01. Streaming por mes: descarga → build shard → upload → delete → siguiente mes. Máximo ~200 MB en disco simultáneos.
- Parse de OCDS: cada record tiene
tender,awards[],contracts[]. Extraemos:description,status,category,amount,buyer,method,date. - Prefix encoding en
.idxusa base36 (los OCIDs son alfanuméricos con guiones — no caben como ints). - Shard format month-indexed propio (
pe-oece-build-sharded.ts) — no migrado auploadWithManifestgenérico (verproject_oece_manifest_migration.mden memoria). Sigue usando legacyuploadToR2con streaming por mes. - Dos índices derivados globales (además de los shards mensuales). Ambos mapean a
compositeId = shardIndex × 1_000_000 + localIndex, que el reader resuelve a (mes, offset) vía el manifest:
- OCID index (
pe-oece-tenders-ocid.bin, magicOCI2): lookup por OCID exacto. Entrada de 12 bytes[key:uint64 LE][compositeId:uint32 LE], ordenado por key.key = ocidHash(ocid)= FNV-1a de 64 bits sobre el string OCID completo (no solo el primer grupo numérico — ver Known issues). La función vive ensrc/oece-ocid-lookup.tsy la importa el builder, así reader y builder comparten una sola fuente. El lookup además verificarecord.ocid === ocidtras leer el record: una colisión de hash (prácticamente imposible) devuelve 404, nunca el record de otra entidad. - RUC index (
pe-oece-ruc-ocid.bin, magicRUCI): lookup de todos los contratos de un proveedor.[ruc_key:uint32][posting_off:uint32][posting_len:uint16]×N+ array decompositeId. INVARIANTE:posting_off/posting_lencuentan en BYTES, no en elementos — el builder avanzapostingByteOff += 4por posting. Escribir índices de elemento desalinea los punteros 4× y un RUC devuelve los contratos de otra empresa (ver Known issues).
Campos publicados
| Field | Type | Example | Notes | ||
|---|---|---|---|---|---|
| ocid | string | ocds-dgv273-seacev3-2024-0001234 | Primary ID. OCDS identifier estándar | ||
| description | string | ADQUISICIÓN DE COMPUTADORAS PARA MINEDU | Searchable. Del objeto del procedimiento | ||
| status | string | active \ | complete \ | cancelled | Status del OCDS (V2 field) |
| category | string | goods \ | works \ | services | Categoría OCDS |
| amount | string | 125000.50 PEN | Monto adjudicado (currency inline) | ||
| buyer | string | MINISTERIO DE EDUCACION | Entidad contratante | ||
| method | string | licitacion_publica \ | concurso_publico | Método de selección | |
| date | string | 2024-03-15 | Fecha del procedimiento |
Single-record por OCID (un OCID = un procedimiento, puede tener múltiples awards/contracts dentro pero los colapsamos).
Limitaciones conocidas
- OCDS v2 vs v3 overlap: los meses 2013-01 y anteriores solo están en v2; desde 2013-02 v3 es canónico. Para evitar duplicación, import filtra por sistema según el mes.
- Campos opcionales en OCDS: OECE no siempre publica
awards[].value.amount— algunos OCIDs tienen monto vacío. Se almacena como string vacío. - Currency inline en
amount: la mayoría PEN, pero algunos procedimientos son en USD. El campo preserva el código. - Migración a manifest pendiente: ver
project_oece_manifest_migration.mden memoria. Sigue usando legacyuploadToR2porque el schema month-indexed (shards por mes, no por hash) no mapea 1-a-1 al manifest genérico. - OCID con guiones — colisión por año (FIXED 2026-05-27, commit
8f1a419): el key viejo (ocidToKey, uint32) capturaba solo el primer grupo numérico del OCID, así que todo OCID hyphenated de un año (...-seacev3-2023-10570-3,...-2023-2543-1985) colisionaba en la key2023y/ocid/:iddevolvía el record de otra licitación. Afectaba el endpoint API y la tool MCPpe_oece_tenders_ocid; el lookup por RUC nunca se afectó (usacompositeIddirecto). Fix: key = hash de 64 bits del OCID completo (OCI2) + verificaciónrecord.ocid. Regresión cubierta entests/unit/oece-ocid-index.test.ts. --currentdestruía los índices derivados (FIXED 2026-05-27, commit7eee068):downloadFromR2(shared.ts) devuelvefalseante cualquier error (incluido un hipo de red transitorio), indistinguible de "no existe". El update entonces reconstruía el índice solo con el mes actual y borraba el histórico, saliendoexit 0. Llegó a dejar el OCID en 11K de ~2.4M. Fix: guard fail-closed enimportCurrent— si hay histórico y la descarga del índice existente falla, o el índice mergeado encoge <50%, aborta sin subir. Follow-ups enbacklog.md(generalizar ashared.ts, retry, tests de floor).- RUCI byte-vs-element offset (FIXED, sesión 2026-05-27): un script suelto (
/tmp/build-ruc-index-only.ts) escribióposting_offcomo índice de elemento en vez de byte → punteros 4× corridos → Peru Activa (textil) "tenía" los contratos de OLC Ingenieros. Reparado in-place + verificado 19,946/19,946. Para rebuilds usar SIEMPRE el builder canónico; el invariante de bytes está comentado enbuildRucIndexFromMap. No re-correr ese script (verbacklog.md).
Estado de revisión y alcance
No se publica todavía una opinión jurídica específica aprobada para esta fuente. La ficha documenta procedencia y transformaciones; Latinfo limita su producto a entidades jurídicas.
Latinfo no está afiliado, certificado ni respaldado por la institución de origen. Para decisiones formales, verifica la evidencia en la fuente primaria. Consulta Privacidad y Términos.