Discovery Readiness API
Metadata Discovery answers only for a client whose existing documents already carry Metadata Leaves. This endpoint tells you whether that is true yet, and what is left to do.
Readiness is scoped to the client that owns the API key. The response never names another client, and it never contains a Custom Metadata value — only paths, counts, and document identities.
Endpoint
GET /discovery/readiness
Requires publication mode. A publication-disabled configuration is rejected at startup because search has no non-publication path.
Request
| Header | Required | Description |
|---|---|---|
X-API-Key | Yes | Valid API key from API_KEY_CLIENTS |
States
| State | Meaning | Metadata / Both available |
|---|---|---|
not_started | No Metadata Backfill has run for this client at the current Metadata Discovery version | No |
backfilling | A backfill has started and has not converged | No |
blocked | At least one document violates the Custom Metadata contract and must be repaired | No |
ready | Every accepted Document Version is represented in Metadata Discovery | Yes |
Content search is available in every state. A non-ready client is a client capability
state, not a service outage: /health stays healthy and Content keeps working.
Response
Ready
{
"state": "ready",
"scopes_available": ["Content", "Metadata", "Both"],
"versions_total": 1284,
"versions_ready": 1284,
"versions_pending": 0,
"versions_blocked": 0,
"totals_known": true,
"active_job_id": null,
"violations": [],
"violations_total": 0,
"violations_truncated": false,
"updated_at": "2026-08-26T09:14:02.117+00:00",
"stale_signature": false,
"reason": null,
"metadata_discovery": {
"metadata_discovery_version": 2,
"dense_model": "BAAI/bge-small-en-v1.5",
"dense_dimensions": 384,
"sparse_model": "ifc:metadata:trigram:v1"
}
}
Backfilling
While an invocation is running, active_job_id is a normal job id: poll it at
GET /status/{job_id}. It becomes null when that invocation exits,
even when deferred or failed work leaves the Client in backfilling.
{
"state": "backfilling",
"scopes_available": ["Content"],
"versions_total": 1284,
"versions_ready": 400,
"versions_pending": 884,
"totals_known": true,
"active_job_id": "6f1f0d0c8b4b4bd2a0d8f0d1a3c7e5b9"
}
Blocked
Violations name the offending document and the Custom Metadata path, never its value.
Repair them with PATCH /update, then re-run the backfill.
{
"state": "blocked",
"scopes_available": ["Content"],
"versions_total": 1284,
"versions_ready": 1283,
"versions_blocked": 1,
"totals_known": true,
"violations": [
{
"document_id": "contract-2024-118",
"version_id": "v3",
"code": "metadata_rendered_leaf_bytes_limit",
"path": ["customer", "notes"],
"observed": 4096,
"limit": 2048,
"unit": "utf8_bytes"
}
],
"violations_total": 1,
"violations_truncated": false
}
violations_truncated is true when more violations exist than the response reports.
violations_total always carries the real count.
Fields
| Field | Description |
|---|---|
state | not_started, backfilling, blocked, or ready |
scopes_available | Search Scopes this client may request right now |
versions_total | Accepted Document Versions in this client's corpus |
versions_ready | Versions already represented in Metadata Discovery |
versions_pending | Versions still needing a backfill |
versions_blocked | Versions blocked by a Custom Metadata contract violation |
totals_known | false only while the initial corpus plan is still determining totals |
active_job_id | The currently running backfill job; null after every terminal return |
violations | Bounded, value-free remediation details |
stale_signature | true when published leaves were built under an incompatible Metadata Discovery version or embedding model |
reason | Why the state is what it is, when a code explains it |
metadata_discovery | The compatibility signature published leaves must carry |
Stale signatures
Changing the Metadata Discovery version, the dense model, its dimensions, or the sparse
model makes previously published leaves incompatible. Readiness then reports
state: "not_started" with stale_signature: true and
reason: "metadata_discovery_signature_changed", and Metadata and Both are gated again
until the reconcile_discovery_readiness sweep converges the client automatically or an
operator re-runs the backfill.
Response Codes
| Code | Description |
|---|---|
| 200 | Success — returns this client's readiness |
| 401 | Unauthorized — invalid or missing API key |
| 503 | Active publication authority or the readiness registry is unavailable |
Related
- Metadata Discovery backfill guide — the operator runbook
- Search API — the
409 METADATA_DISCOVERY_NOT_READYconflict - Status API — polling a running backfill