Skip to main content

governance

GET /models/{model_id}/card:export​

Export a model card as markdown or PDF

Renders the model card deterministically (WP-A7 reqs 4 and 10). For a model whose newest bundle pinned a card, the render is that pinned card (https://spec.tessera.dev/schemas/pinned_model_card.json), governance fields included as they stood at promotion. The bundle manifest is first loaded from storage and verified against its recorded fingerprint; the stored card.json is then re-hashed against that verified manifest's card_fingerprint before it is parsed. Any mismatch fails closed with 400 failed_precondition and typed \{kind, uri, expected, actual\} detail (WP-M15 req 4 discipline). When the model's governance fields changed after the pin, the pinned card is rendered unchanged followed by a separately labelled "Current governance (updated after promotion, as of <updated_at>)" block, and governance_updated_after_pin is true. Otherwise (an unpromoted model, or a newest bundle created without a pinned card) the render is the current-state card assembled on read plus the model's current governance fields, marked with an explicit UNPINNED watermark and pinned: false. Renders are pure functions of their inputs: two exports of the same pinned card and governance state are byte-identical, and every date comes from the recorded content, never from the clock. The rendered bytes are returned inside a JSON envelope (UTF-8 text for markdown, base64 for PDF) with their length and SHA-256; a render larger than 10 MiB is refused with 400 failed_precondition and typed detail \{type: render_size, reason: render_too_large, limit_bytes, byte_length\}. A PDF render that cannot draw some characters faithfully (no glyph in the embedded font, a right-to-left script, a combining mark, a control or format character) is refused, never drawn garbled: 400 failed_precondition with typed detail \{type: render_unsupported_text, reason: unsupported_characters, format: pdf, characters, alternatives\}, where characters lists up to 50 refused code points as sorted U+XXXX strings and alternatives names the formats of this operation that carry the text verbatim (markdown). A model that has not been evaluated yet, or another tenant's model id, is 404 not_found (003 §3).

Operation ID: exportModelCard · Service: gateway-api

Authentication​

  • apiKey (http (bearer)) — Project API key (003 §2): tsk_live_… or tsk_test_… in Authorization: Bearer. Scoped to exactly one project + environment; scopes are a subset of ingest, read, admin. Keys are stored hashed and shown once at creation.
  • consoleSession (http (bearer)) — Console session (003 §2): Identity Platform JWT. Data-plane calls add X-Tessera-Project + X-Tessera-Environment headers, validated against org membership.

Parameters​

NameInRequiredTypeDescription
model_idpathyesstringModel version id (mdl_ ULID, 002 §1).
formatquerynostringRender format; defaults to markdown.

Responses​

StatusSchemaDescription
200ModelCardExportThe rendered model card.
defaultErrorEnvelopeError response (003 §1). Every non-2xx response uses this envelope; the HTTP status matches error.code. Rate-limited requests get 429 resource_exhausted with retry_after_seconds and a Retry-After header; the X-RateLimit-* headers ride on EVERY response, success or error (003 §1; plan-driven per API key + endpoint class — WP-B2). A 503 unavailable carries retry_after_seconds too for a lock-wait timeout (SQLSTATE 55P03), a rule preview at capacity (preview_capacity_exhausted), or a label preview during which the erasure of every entity holding its censor clock began (label_preview_clock_entity_erased): how long to wait before retrying.

GET /models/{model_id}/governance​

Get a model's authored governance fields

The authored intended use, limitations and usage restrictions of the model version (WP-A7 req 3; https://spec.tessera.dev/schemas/governance_fields.json) with the last update's actor and instant. governance is an empty object until a field is authored. Exported model cards and every dossier render these fields verbatim; the served GET /models/\{model_id\}/card response is unchanged (closed v1 response, ERRATA 2026-10-12 WP-A7). Another tenant's model id is 404 not_found (003 §3).

Operation ID: getModelGovernance · Service: gateway-api

Authentication​

  • apiKey (http (bearer)) — Project API key (003 §2): tsk_live_… or tsk_test_… in Authorization: Bearer. Scoped to exactly one project + environment; scopes are a subset of ingest, read, admin. Keys are stored hashed and shown once at creation.
  • consoleSession (http (bearer)) — Console session (003 §2): Identity Platform JWT. Data-plane calls add X-Tessera-Project + X-Tessera-Environment headers, validated against org membership.

Parameters​

NameInRequiredTypeDescription
model_idpathyesstringModel version id (mdl_ ULID, 002 §1).

Responses​

StatusSchemaDescription
200ModelGovernanceThe model's authored governance fields.
defaultErrorEnvelopeError response (003 §1). Every non-2xx response uses this envelope; the HTTP status matches error.code. Rate-limited requests get 429 resource_exhausted with retry_after_seconds and a Retry-After header; the X-RateLimit-* headers ride on EVERY response, success or error (003 §1; plan-driven per API key + endpoint class — WP-B2). A 503 unavailable carries retry_after_seconds too for a lock-wait timeout (SQLSTATE 55P03), a rule preview at capacity (preview_capacity_exhausted), or a label preview during which the erasure of every entity holding its censor clock began (label_preview_clock_entity_erased): how long to wait before retrying.

PATCH /models/{model_id}/governance​

Update a model's authored governance fields

Merge-patches the model version's authored governance fields (WP-A7 req 3): a field absent from the body is unchanged, null removes it and a value replaces it. Unknown fields, an empty body and invalid values are 400 invalid_argument (deny by default). The write and exactly one governance.update audit event, whose details carry the before and after field values, commit in the same transaction. The fields belong to the model version: promoting it pins the values in force into the bundle's model card. Another tenant's model id is 404 not_found (003 §3).

Operation ID: updateModelGovernance · Service: gateway-api

Authentication​

  • apiKey (http (bearer)) — Project API key (003 §2): tsk_live_… or tsk_test_… in Authorization: Bearer. Scoped to exactly one project + environment; scopes are a subset of ingest, read, admin. Keys are stored hashed and shown once at creation.
  • consoleSession (http (bearer)) — Console session (003 §2): Identity Platform JWT. Data-plane calls add X-Tessera-Project + X-Tessera-Environment headers, validated against org membership.

Parameters​

NameInRequiredTypeDescription
model_idpathyesstringModel version id (mdl_ ULID, 002 §1).

Request body​

GovernanceFieldsPatch

Responses​

StatusSchemaDescription
200ModelGovernanceThe model's governance fields after the update.
defaultErrorEnvelopeError response (003 §1). Every non-2xx response uses this envelope; the HTTP status matches error.code. Rate-limited requests get 429 resource_exhausted with retry_after_seconds and a Retry-After header; the X-RateLimit-* headers ride on EVERY response, success or error (003 §1; plan-driven per API key + endpoint class — WP-B2). A 503 unavailable carries retry_after_seconds too for a lock-wait timeout (SQLSTATE 55P03), a rule preview at capacity (preview_capacity_exhausted), or a label preview during which the erasure of every entity holding its censor clock began (label_preview_clock_entity_erased): how long to wait before retrying.

GET /orgs/{org_id}/model-inventory​

List the organization's model inventory

Every model version and every deployment slot of every project and environment of the organization, exactly once each (WP-A7 req 2; https://spec.tessera.dev/schemas/model_inventory.json), ordered by project, then kind (models before slots), then creation instant and id (cursor pagination, 003 §1). Each row copies its facts from their single sources and is absent-tolerant: the environment, the G1–G6 gate statuses, the server-resolved promotion verdict and the acknowledgement provenance (WP-M14, verbatim), the gbm_v1 internal safeguard comparison (WP-M8), the pinned card fingerprint and the last-validated instant. Model rows name their owner, the actor of the newest bundle's bundle.create audit event; slot rows name last_activated_by, the actor recorded on the slot's newest activation history entry (activate or rollback, from the durable append-only slot history), which records who last put a bundle into service and is not an ownership claim. Both are null when unattributed and are never fabricated. Shared-checkpoint imports are model rows (origin: shared_checkpoint). A source that fails verification never blocks a page: its row is still listed, the facts derived from that source are withheld, and facts_withheld_reason names the source and its typed mismatch. Projects are read one at a time with tenancy bound to that project (004 §2 rule 2). Requires org role admin or a custom role granting model_inventory.list (WP-A5); another org's id is 404 not_found (003 §3). Console sessions only.

Operation ID: listOrgModelInventory · Service: gateway-api

Authentication​

  • consoleSession (http (bearer)) — Console session (003 §2): Identity Platform JWT. Data-plane calls add X-Tessera-Project + X-Tessera-Environment headers, validated against org membership.

Parameters​

NameInRequiredTypeDescription
org_idpathyesstringOrganization id (org_ ULID).
cursorquerynostringOpaque pagination cursor from a previous response's next_cursor.
limitquerynointegerPage size (cursor pagination, 003 §1). Maximum 200.

Pagination​

Cursor pagination (003 §1): pass limit (max 200) and cursor; the response is the pagination envelope — data plus next_cursor (null on the last page).

Responses​

StatusSchemaDescription
200ModelInventoryPagePage of inventory rows.
defaultErrorEnvelopeError response (003 §1). Every non-2xx response uses this envelope; the HTTP status matches error.code. Rate-limited requests get 429 resource_exhausted with retry_after_seconds and a Retry-After header; the X-RateLimit-* headers ride on EVERY response, success or error (003 §1; plan-driven per API key + endpoint class — WP-B2). A 503 unavailable carries retry_after_seconds too for a lock-wait timeout (SQLSTATE 55P03), a rule preview at capacity (preview_capacity_exhausted), or a label preview during which the erasure of every entity holding its censor clock began (label_preview_clock_entity_erased): how long to wait before retrying.

GET /slots/{slot}/governance​

Get a slot's authored governance fields

The authored intended use, limitations and usage restrictions of the deployment slot (WP-A7 req 3; https://spec.tessera.dev/schemas/governance_fields.json) with the last update's actor and instant. governance is an empty object until a field is authored. Dossiers whose subject is the slot render these fields verbatim. Another project's slot is 404 not_found (003 §3).

Operation ID: getSlotGovernance · Service: gateway-api

Authentication​

  • apiKey (http (bearer)) — Project API key (003 §2): tsk_live_… or tsk_test_… in Authorization: Bearer. Scoped to exactly one project + environment; scopes are a subset of ingest, read, admin. Keys are stored hashed and shown once at creation.
  • consoleSession (http (bearer)) — Console session (003 §2): Identity Platform JWT. Data-plane calls add X-Tessera-Project + X-Tessera-Environment headers, validated against org membership.

Parameters​

NameInRequiredTypeDescription
slotpathyesstringDeployment slot reference: the slot id (slot_ ULID, 002 §1) or the per-project-unique slot name (002 §9 — the stable API-addressable unit; names never contain _, so the two forms are disjoint). A slot belonging to another project or environment is indistinguishable from a missing one (404 not_found, 003 §3).

Responses​

StatusSchemaDescription
200SlotGovernanceThe slot's authored governance fields.
defaultErrorEnvelopeError response (003 §1). Every non-2xx response uses this envelope; the HTTP status matches error.code. Rate-limited requests get 429 resource_exhausted with retry_after_seconds and a Retry-After header; the X-RateLimit-* headers ride on EVERY response, success or error (003 §1; plan-driven per API key + endpoint class — WP-B2). A 503 unavailable carries retry_after_seconds too for a lock-wait timeout (SQLSTATE 55P03), a rule preview at capacity (preview_capacity_exhausted), or a label preview during which the erasure of every entity holding its censor clock began (label_preview_clock_entity_erased): how long to wait before retrying.

PATCH /slots/{slot}/governance​

Update a slot's authored governance fields

Merge-patches the deployment slot's authored governance fields (WP-A7 req 3): a field absent from the body is unchanged, null removes it and a value replaces it. Unknown fields, an empty body and invalid values are 400 invalid_argument (deny by default). The write and exactly one governance.update audit event, whose details carry the before and after field values, commit in the same transaction. The fields belong to the slot and persist while bundles rotate under it. Another project's slot is 404 not_found (003 §3).

Operation ID: updateSlotGovernance · Service: gateway-api

Authentication​

  • apiKey (http (bearer)) — Project API key (003 §2): tsk_live_… or tsk_test_… in Authorization: Bearer. Scoped to exactly one project + environment; scopes are a subset of ingest, read, admin. Keys are stored hashed and shown once at creation.
  • consoleSession (http (bearer)) — Console session (003 §2): Identity Platform JWT. Data-plane calls add X-Tessera-Project + X-Tessera-Environment headers, validated against org membership.

Parameters​

NameInRequiredTypeDescription
slotpathyesstringDeployment slot reference: the slot id (slot_ ULID, 002 §1) or the per-project-unique slot name (002 §9 — the stable API-addressable unit; names never contain _, so the two forms are disjoint). A slot belonging to another project or environment is indistinguishable from a missing one (404 not_found, 003 §3).

Request body​

GovernanceFieldsPatch

Responses​

StatusSchemaDescription
200SlotGovernanceThe slot's governance fields after the update.
defaultErrorEnvelopeError response (003 §1). Every non-2xx response uses this envelope; the HTTP status matches error.code. Rate-limited requests get 429 resource_exhausted with retry_after_seconds and a Retry-After header; the X-RateLimit-* headers ride on EVERY response, success or error (003 §1; plan-driven per API key + endpoint class — WP-B2). A 503 unavailable carries retry_after_seconds too for a lock-wait timeout (SQLSTATE 55P03), a rule preview at capacity (preview_capacity_exhausted), or a label preview during which the erasure of every entity holding its censor clock began (label_preview_clock_entity_erased): how long to wait before retrying.

Errors​

Every non-2xx response uses the 003 §1 error envelope; error.request_id matches the X-Request-Id response header, and the HTTP status always matches error.code:

{
"error": {
"code": "invalid_argument",
"details": [
{
"type": "field_violation"
}
],
"message": "human-readable",
"request_id": "req_01hxample"
}
}

Closed error-code set (003 §1): invalid_argument, unauthenticated, permission_denied, not_found, already_exists, failed_precondition, resource_exhausted, internal, unavailable.

resource_exhausted responses (HTTP 429) additionally carry retry_after_seconds. See ErrorEnvelope.