POST /v1/extract, versioned immutably under a stable
sch_... id. Create a family, append new versions, and pin a version from Extract
with schema_version (omit it to use latest).
Tenant keys create and append only their own schemas. Reads include tenant and
platform schemas; when both share a schema_id, the tenant row wins.
All list routes use keyset cursor pagination (cursor / next_cursor).
Out of scope for this surface: drafts, in-place updates, archive/delete.
List extraction schemas
cursor(optional) — Opaque cursor from a previous page’snext_cursor.limit(optional, default 50, max 200) — Rows per page.
schema_id— Stable family id (sch_...).name/description— Snapshotted on the latest version.version— Highest integer version in the winning ownership scope.owner—tenantorplatform.
Create extraction schema
schema_id.
Request:
name(required, max 128) — Human-readable label for this version.description(optional, max 2000) — Longer explanation.schema(required) — JSON Schema. Validated with the same compiler Extract uses; invalid schemas are refused withinvalid_schemaand not written.
schema, version=1, and generated schema_id.
Get extraction schema
schema_not_found(404) — Unknown id, or a schema owned only by another tenant.
List extraction schema versions
cursor / limit as list.
Create extraction schema version
schema_not_found.
Request:
schema(required) — New JSON Schema body (compiler-validated before write).name(optional) — Defaults to the previous version’s name.description(optional) — Defaults to the previous version’s description.
version = previous + 1).
Get extraction schema version
version ≥ 1).
Errors:
schema_not_found(404) — Family or version not visible to the caller.
Using a registry schema with Extract
- Omit
schema_versionto resolve latest. - Exactly one of
schema_id/schemaon the wire. - Accept-time freeze stores the effective JSON Schema on the job and records the
resolved id/version for
ExtractResult.schema_id/schema_version.