Skip to main content

dossiers

GET /dossier-templates​

List the dossier template catalog

The fingerprint-locked dossier template catalog, verbatim (WP-A7 req 5; the GET /gate-definitions precedent): every template exactly as shipped in the tessera_core.governance catalog data (https://spec.tessera.dev/schemas/dossier_template.json) plus the server-computed template_fingerprint, the 002 §10 canonical-JSON fingerprint of the data file. Ordered by template_id. The catalog is small and never paginated, so next_cursor is always null.

Operation ID: listDossierTemplates · 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.

Responses​

StatusSchemaDescription
200DossierTemplatePageThe complete dossier template catalog.
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 /dossiers​

List dossiers

Dossiers of the resolved project and environment, newest first (cursor pagination, 003 §1). Optional filters narrow by template or by subject. Requires the same access as the project audit feed (WP-A3), because dossiers embed audit extracts.

Operation ID: listDossiers · 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
cursorquerynostringOpaque pagination cursor from a previous response's next_cursor.
limitquerynointegerPage size (cursor pagination, 003 §1). Maximum 200.
model_idquerynostringOnly dossiers whose subject is this model version.
slot_idquerynostringOnly dossiers whose subject is this slot.
template_idquerynostringOnly dossiers assembled under this template id.

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
200DossierPagePage of dossiers, newest first.
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.

POST /dossiers​

Assemble a dossier

Assembles one immutable, fingerprinted dossier (dos_; https://spec.tessera.dev/schemas/dossier.json) for one subject under one catalog template (WP-A7 reqs 5-10). subject names exactly one of model_id or slot_id (both or neither are 400 invalid_argument); a template that does not accept that subject kind is 400 invalid_argument; an unknown template id is 404 not_found. A template whose data file no longer matches its recorded fingerprint fails closed with 400 failed_precondition naming the mismatch. Every section either embeds its evidence, each entry carrying \{kind, source, fingerprint\}, or states evidence: missing with the reason (for example source_not_bound); evidence is never fabricated or silently omitted. When the subject's bundle enables behavioral signals the label-free anomaly section is always present. The audit-extract section embeds at most 500 events and states truncated and total_count, so a capped extract is never silent. Assembly renders all three download formats before anything is stored or audited: if any render exceeds the 10 MiB download cap the request is refused with 400 failed_precondition and typed detail \{type: render_size, reason: render_too_large, limit_bytes, byte_length\}, so no stored dossier is ever too large to download. (Text the PDF render cannot draw faithfully does not refuse assembly: json and markdown carry it verbatim, and the PDF download is refused with render_unsupported_text.) The stored document, its row and exactly one dossier.create audit event commit together. Re-assembly mints a new dossier_id and leaves earlier dossiers untouched. Requires the same access as the project audit feed (WP-A3), because dossiers embed audit extracts.

Operation ID: createDossier · 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
Idempotency-KeyheadernostringIdempotency key accepted by all POSTs (003 §1): 24 h dedup window, keyed per project. POSTs that are reads (batchSlotScores, scoreSlotEvent, deriveSlotBands, validateSourceRawPreset, sampleSource, watchEventFeedHeads and the preview operations: previewSourceMapping, previewCatalogMapping, previewLabel, previewPatternLabel, previewMarker, previewDatasetEligibility, previewSlotAudience, previewSharedCheckpointImport, previewSlotAtlasInquiry) accept the key but never replay a stored response: a retry with the same key is executed again (and metered again) against current data. A stored response that names an entity is removed when that entity is erased. A key that already answered answers only a retry of the request that stored its response: the same caller, environment, operation, path, query, scoping headers and body (a JSON body by its content, a gzip body by its inflated content). The same key with any other request is 409 already_exists with details[0].reason idempotency_key_reused, and that request is not run. The window holds no in-flight marker: two first requests sent at once can both run. A response stored by a release before this rule cannot be matched to its request and is refused the same way until it expires; send the request again with a new key. A body over 8 MiB (ingest: over its 5 MiB request limit) is run and its response is not stored. The ingest batch (POST /events) is the exception, except for an application's credentials: under a key that answered another batch it runs again, uncached, and its events' ids deduplicate them; so it does when its stored response cannot be checked. The operations that return a one-time secret store their response sealed: the stored copy opens only for the same key and credential, and one that cannot be opened is 409 idempotency_key_reused. While the server cannot check a stored response (it cannot read the key that checks it, for one), the request is 503 unavailable with Retry-After: retry with the same key. An operation whose handler claims the key itself answers the same 503, before it runs, while the key-hash pepper cannot be read; any other request sent with a key runs meanwhile, and its response is not stored.

Idempotency​

This operation accepts an Idempotency-Key header (003 §1): within 24 hours, keyed per project and caller, a retry of the same request gets the first response, and the same key with another request is 409 already_exists (idempotency_key_reused). See the Idempotency-Key parameter for the exceptions.

Request body​

DossierCreateRequest

Responses​

StatusSchemaDescription
201DossierThe assembled dossier.
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 /dossiers/{dossier_id}​

Get a dossier

One dossier's identity, template, subject, fingerprint and per-section evidence status. The full document is read through GET /dossiers/\{dossier_id\}:download. Another project's dossier is 404 not_found (003 §3).

Operation ID: getDossier · 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
dossier_idpathyesstringDossier id (dos_ ULID, 002 §1).

Responses​

StatusSchemaDescription
200DossierThe dossier.
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 /dossiers/{dossier_id}:download​

Download a dossier as JSON, markdown or PDF

Renders the stored dossier (WP-A7 reqs 8 and 10). The stored dossier.json is re-hashed against the SHA-256 recorded when it was assembled (content_sha256) before it is parsed, and its self-fingerprint is then confirmed against the recorded fingerprint (ERRATA 2026-10-12, WP-A7 downloadDossier). Tampered bytes fail closed with 400 failed_precondition and typed \{kind, uri, expected, actual\} detail. json returns the stored canonical bytes; markdown and pdf are pure functions of them, so repeated downloads in any format are byte-identical. The rendered bytes are returned inside a JSON envelope (UTF-8 text for json and 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 (json and markdown). Another project's dossier is 404 not_found (003 §3).

Operation ID: downloadDossier · 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
dossier_idpathyesstringDossier id (dos_ ULID, 002 §1).
formatquerynostringRender format; defaults to json.

Responses​

StatusSchemaDescription
200DossierDownloadThe rendered dossier.
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.