---
title: "Comprobar si un lote importado ya está disponible para segmentar"
method: POST
path: "/import-sync/readiness"
tags: ["Import Sync"]
---

# Comprobar si un lote importado ya está disponible para segmentar

`POST /import-sync/readiness`

## Request

- Base URL: `http://localhost:8081`
- URL: `http://localhost:8081/import-sync/readiness`
- Auth: HTTP bearer

Endpoint servicio-a-servicio consumido por el reconciliador de importaciones de
nev-api. **No acepta JWT de usuario.**

Demuestra, usuario a usuario y campo a campo, que los datos aceptados por una
importación han llegado al mart que lee la segmentación. Un recuento de filas o una
ventana temporal no lo demuestran: los satisface igualmente un dato que nunca cambió.

Para cada entrada se compara la huella que nev-api calcula desde el documento ACTUAL
de origen con la que BigQuery calcula desde la fila del mart, usando la misma
codificación canónica (`n:` si el valor es nulo o ausente, `s:` + el valor en caso
contrario; SHA-256 sobre bytes UTF-8 en hexadecimal minúscula).

Lo que se demuestra en campos personalizados es la **proyección que el consumidor
lee**: `property_name`, `data_type` y `typed_value` no nulos, y la huella de
`typed_value` igual a la esperada. `raw_value` no es prueba: coincide en casos que el
selector no puede mostrar (un valor LIST cuya extracción escalar deja `typed_value`
nulo), y darlo por bueno certificaba campos que la segmentación no puede usar.

Contrato opcional v2 (`contractVersion: 2`): prueba histórica de un candidato fijo,
identificado por `candidateRevision`. Exige versión exacta y la misma imagen en
users/user_tenants, valores tipados y marcadores de campos personalizados, y presencia
o ausencia de cada etiqueta del ámbito por fila. No certifica escrituras futuras.
Una imagen posterior devuelve `candidate_superseded`, nunca READY automático.
La respuesta devuelve `proofs` para TODOS los candidatos y su revisión recibida.
Finalizar requiere lote vacío, `bumpCatalogVersionOnReady: true` y `finalizationId`
estable por job/época; un replay reutiliza el recibo de catálogo transaccional.

Reglas que no admiten atajo:

- Una edición posterior no exime la prueba: nev-api recalcula la expectativa, así que
  la edición cambia lo que hay que demostrar.
- Un valor marcado como ambiguo por la vista resuelta queda pendiente aunque coincida.
- Un valor presente pero inutilizable (metadatos o `typed_value` nulos) queda pendiente
  con `field:cf:<id>:unusable`; nunca READY.
- La ausencia también es una expectativa: si el origen no tiene valor (huella de `n:`)
  y el mart no tiene fila, está consumido. Si el mart conserva un valor que el origen
  ya borró, queda pendiente con `field:cf:<id>:stale`.
- Un borrado de usuario sí es terminal: si el mart marca el usuario como borrado no
  queda nada que demostrar sobre sus campos.

El lote está listo cuando `pending` es 0. `missing` devuelve una entrada por cada
prueba fallida, de modo que un mismo usuario puede aparecer varias veces.

## Headers

- `x-service` 'nev-api', required
- `x-tenant-id` string, required

## Request body

- object
  - `contractVersion` 2: Opcional; su ausencia conserva el contrato legacy.
  - `finalizationId` string: Identidad estable job/época para finalizar v2 de forma idempotente.
  - `jobId` string, required: Job de importación al que pertenece el lote. Obligatorio y no vacío: junto con `chunkIndex` es lo que permite rastrear la respuesta hasta su lote en Cloud Logging. Se rechaza con 400 si falta o no es una cadena con contenido.
  - `chunkIndex` integer, required: Índice del lote dentro del manifiesto. Obligatorio, entero y no negativo (0 es el primer lote). Se rechaza con 400 en cualquier otro caso.
  - `importLabelId` string, nullable: Etiqueta aplicada por la importación; si viene, se exige pertenencia
  - `bumpCatalogVersionOnReady` boolean: Incrementa la versión de catálogo del tenant si el lote está listo. La invalidación es un paso de job completo, no de lote: llega una sola vez, con `entries` vacío, cuando todos los lotes están READY.
  - `entries` object[], required: Expectativas recalculadas desde los documentos actuales de origen. Puede ir vacío **solo** con `bumpCatalogVersionOnReady: true`: es la invalidación de catálogo a nivel de job, que llega cuando todos los lotes ya están listos. Vacío sin esa petición se rechaza con 400.
    - `candidateRevision` string: Obligatoria en v2; identidad inmutable del candidato, devuelta en su prueba.
    - `proofScope` 'user-document-derived': Obligatorio en v2. Certifica los insumos del documento de usuario; excluye la frescura de enriquecimientos de compras/clics.
    - `consumerFields` object: Obligatorio en v2; mapa exacto de 28 huellas snake_case del contrato de imagen consumidora, incluidas preferencias y contactabilidad. created_at usa UTC YYYY-MM-DDTHH:mm:ss.SSSZ.
    - `labels` object: V2; IDs de etiquetas importadas por fila y segmento; true exige presencia de la misma imagen, false exige ausencia.
    - `userId` string, required
    - `sourceVersion` integer, required: modifiedAt actual del documento de origen, en epoch ms
    - `deleted` boolean, required: Estado de borrado actual en origen
    - `fields` object, required: Huella por campo mapeado. Claves `cf:<propertyDefinitionId>` para campos personalizados y, para campos estándar, exactamente `std:email`, `std:name`, `std:phone`, `std:fiscalId` y `std:lang`: son los únicos que conservan una columna 1:1 en el mart. Cualquier otra clave se rechaza con 400 nombrándola, en lugar de quedarse pendiente para siempre sobre una prueba que nadie puede satisfacer.

## Response `200`

Comprobación realizada

- object
  - `success` boolean
  - `data` object
    - `contractVersion` 2
    - `queryStatistics` object: V2, estadísticas de la consulta única de esta página. Se omiten si BigQuery no devuelve metadatos completos; ausencia no significa coste cero. El consumidor deduplica por jobId antes de acumular. Los enteros se transmiten como cadenas decimales exactas.
      - `jobId` string, required
      - `bytesProcessed` string, required
      - `bytesBilled` string, required
      - `cacheHit` boolean, required
      - `slotMs` string, required
    - `proofs` object[]: V2, una entrada por candidato incluyendo pendientes; el cliente debe cercar por candidateRevision.
      - `userId` string
      - `candidateRevision` string
      - `proofScope` 'user-document-derived'
      - `sourceVersion` integer
      - `observedSourceVersion` integer, nullable
      - `recordTs` string, nullable: Epoch microseconds as an exact string
      - `proofKind` 'PROVEN' | 'REMOVED' | 'PENDING'
    - `consumed` integer: Entradas demostradas
    - `pending` integer: Entradas sin demostrar; el lote está listo cuando vale 0
    - `missing` object[]: Una entrada por prueba fallida (un usuario puede repetirse)
      - `userId` string
      - `reason` string: `version`, `deleted`, `label`, `field:<clave>`, `field:<clave>:ambiguous`, `field:<clave>:unusable` (metadatos o `typed_value` nulos) o `field:<clave>:stale` (el origen borró el valor y el mart lo conserva). V2 añade `candidate_superseded`, `membership`, `membership:stale`, `consumer_version`, `custom_version`, `consumer_input:<clave>`, `source_input:<clave>`, `consumer_field:<clave>`, `label:<id>`, `label:<id>:stale` y `label:<id>:not_in_tenant_catalog`.
    - `source` 'legacy' | 'resolved': Origen de campos personalizados con el que se comprobó
    - `catalogVersion` integer, nullable: Nueva versión de catálogo si se pidió y el lote estaba listo
  - `timestamp` string, date-time

## Other responses

- `400`: Petición inválida: `jobId` o `chunkIndex` ausentes o mal formados, más de 1000 entradas, `entries` vacío sin `bumpCatalogVersionOnReady`, una entrada mal formada, o una clave de campo no soportada. El mensaje nombra siempre el campo o la clave. No se ejecuta ninguna consulta.
- `401`: Token de servicio, x-service o x-tenant-id ausentes o inválidos
- `500`: Error interno del servidor
- `503`: SERVICE_TOKEN no configurado, o presupuesto de consulta excedido. En el segundo caso `errorCode=READINESS_BUDGET`: el reconciliador debe detener las consultas automáticas y mostrar la necesidad de intervención.

---

[API](https://skmtc.dev/nevent/apis/nevent-data-api.md) · [All operations](https://skmtc.dev/nevent/apis/nevent-data-api/llms.txt) · [OpenAPI document](https://skmtc.dev/nevent/apis/nevent-data-api/revisions/81035d32c1c1?raw)
