Skip to main content

proof

GET /backtests​

List backtests

Standard-protocol backtests of the resolved project + environment, newest first (cursor pagination, 003 §1), optionally filtered by protocol and model.

Operation ID: listBacktests · 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_idquerynostring
protocol_idquerynostring

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
200BacktestPagePage of backtests, 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 /backtests​

Backtest a model against a protocol

Launches a backtest of a model — addressed by model_id, by slot (its active bundle) or by bundle_id — and returns 202 with the backtest's index row (status: running). The default engine, dataset_anchored_test_split, runs in the eval Job over the model's dataset test split; full_book_out_of_time rescores the full entity book of a bundle (a slot or bundle_id; a model_id alone is failed_precondition, reason bundle_required) through the WP-V1 cutoff semantics with a non-serving sink, over the dataset's pinned event-store snapshot, at cutoffs strictly after the model's training cutoff (its dataset's time_range end). For each declared label and each arm (the model, the protocol's safeguard arms and comparators) the report carries the share of positives alerted at least d days before their outcome on the fixed grid d ∈ {0, 1, 2, 3, 5, 7, 14, 21, 30, 45, 60, 90} at the protocol's alert_budget, plus median lead days, each with an entity-bootstrap 95% CI, and the regime (prefix_only or observation_time). Every arm divides by the label's n_eligible(d); for prefix_only arms an alert counts only at the first cutoff or after the entity had an event since the previous cutoff, and first_alert_in_silence is the per-arm count of positives whose first raw alert fell in a silence-bounded interval and was not counted. cutoffs is optional (2-12 strictly ascending RFC 3339 instants inside the engine window, invalid_argument otherwise); without it the server uses 6 evenly spaced cutoffs over the engine window, resolved at request time and recorded (cutoffs_source: default_even); the backtest identity uses the resolved request. The full_book_out_of_time window ends at the earliest of the dataset's event-store snapshot instant, the data's censor clock (where the dataset's events end, which a finite export reaches before its snapshot) and the request instant, minus the largest maturation_days of the protocol's labels (an empty window is failed_precondition, reason full_book_window_empty; a data file of the dataset's pinned snapshot whose bytes differ from its manifest is failed_precondition, reason snapshot_file_mismatch). Outcomes are read as of the dataset snapshot (dataset_anchored_test_split) or as of EXACTLY the last cutoff plus the largest maturation_days of the protocol's labels (full_book_out_of_time; 400 invalid_argument if that instant is in the future); the report records it (outcomes_as_of) with the label manifest fingerprints. A protocol with lead_time_metrics adds a pass | fail | not_evaluated verdict on the paired model-minus-arm lead-time deltas. The backtest never refreshes a slot or writes served state. The protocol must have been declared strictly before the model's dataset build (protocol_after_data otherwise). The backtest identity is the RESOLVED model and bundle (with its fingerprint), not the addressing: a slot- and a bundle-addressed request that resolve to the same bundle return the same backtest, the slot is metadata recorded from the request that created it, and the recompute appendix replays it by bundle_id. A slot with no active bundle is 400 failed_precondition (slot_without_active_bundle). A hazard-ablation protocol id (WP-M17) is 404 not_found here. An identical request returns the existing backtest.

Operation ID: createBacktest · 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​

BacktestCreateRequest

Responses​

StatusSchemaDescription
202BacktestThe backtest's index row: a new acceptance, or the identical existing backtest (same backtest_id, its current status).
400ErrorEnvelope400 for the proof create operations (WP-M20/WP-M22), in the 003 §1 envelope: invalid_argument, or failed_precondition. When the protocol was not declared strictly before the judged dataset build, details[0] is a ProtocolAfterDataDetail (type: precondition_failure, reason: protocol_after_data, protocol_id, declared_at, dataset_id, dataset_created_at). When another signals evaluation of the model is running (POST /models/\{model_id\}/signals-evaluations), details[0] is \{type: precondition_failure, reason: evaluation_in_progress, report_id\}. A slot-addressed backtest whose slot has no active bundle is failed_precondition with reason: slot_without_active_bundle. For POST /models/\{model_id\}/observation-ablations (WP-M16): another observation ablation of the model running is evaluation_in_progress with its report_id, as above; a model whose config does not consume the elapsed-silence token is failed_precondition with reason: observation_time_model_disabled; a without_token_model_id whose config consumes it is failed_precondition with reason: observation_ablation_twin_consumes_token; a without_token_model_id that is not the model's flag-off twin is failed_precondition with reason: observation_ablation_not_twin; a model or twin whose files are being or were deleted is failed_precondition with reason: model_files_purged (model_id names which, status); naming the model itself or an event model as without_token_model_id is invalid_argument. For POST /evaluations:baseline (WP-M22 req 8), a new evaluation whose runtime estimate exceeds the shared evaluation pool's 6 h deadline is failed_precondition with reason: runtime_budget_exceeded, estimated_seconds, ceiling_seconds, budget_seconds (the declared 45 min target), the shape it was computed from (entity_count, row_count, event_count, label_count, arm_count, comparator_count) and the reference shape.
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 /backtests/{backtest_id}​

Get a backtest

The standard-protocol backtest's index row plus, once it has succeeded, the stored backtest_report.json verbatim (re-hashed against the recorded fingerprint before it is served, 002 §10 — fail closed). A row still running after 6 h reads as failed with reason timeout. Another tenant's id is 404 not_found (003 §3). A stored report that fails verification is 400 failed_precondition: reason artifact_fingerprint_mismatch with detail \{kind, uri, expected, actual\} (actual is missing for an absent object), or artifact_malformed with \{kind, uri\} for verified bytes that are not the report document.

Operation ID: getBacktest · 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
backtest_idpathyesstringBacktest id (bkt_, 002 §1).

Responses​

StatusSchemaDescription
200BacktestDetailThe backtest.
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 /evaluations​

List protocol evaluations

Standard protocol evaluations (model and baseline basis; never the WP-M17 hazard-ablation evaluations) of the resolved project + environment, newest first (cursor pagination, 003 §1), optionally filtered by protocol and dataset build — the side-by-side view of a model's verdict next to the baseline bar.

Operation ID: listEvaluations · 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.
dataset_idquerynostring
limitquerynointegerPage size (cursor pagination, 003 §1). Maximum 200.
protocol_idquerynostring

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
200ProofEvaluationPagePage of evaluations, 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 /evaluations​

Evaluate a model against a protocol

Launches the evaluation Job for a model with the decision half taken from the protocol (safeguard arms, inline banding policy, margins, comparators) and returns 202 with the evaluation's index row (status: running). The report gains a verdict (one pass | fail | not_evaluated row per declared criterion; overall pass | fail | incomplete) and an evaluation_basis, read through GET /evaluations/\{report_id\}. The request never restates criteria (unknown fields are 400 invalid_argument). The protocol must have been declared strictly before the model's dataset build (protocol_after_data otherwise). The protocol fingerprint is part of the report's content-derived identity, so the same model judged under two protocols gets two immutable reports; an identical request returns the existing evaluation. The report recomputes the gates with the same inputs but never becomes the model's evaluation of record: the promotion pointer keeps referencing the model's own evaluation. Verdicts are advisory: no promotion, serving or delivery path reads them. A hazard-ablation protocol id (WP-M17) is 404 not_found here.

Operation ID: createEvaluation · 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​

EvaluationCreateRequest

Responses​

StatusSchemaDescription
202ProofEvaluationThe evaluation's index row: a new acceptance, or the identical existing evaluation (same report_id, its current status; the createDatasetBuild idempotency precedent).
400ErrorEnvelope400 for the proof create operations (WP-M20/WP-M22), in the 003 §1 envelope: invalid_argument, or failed_precondition. When the protocol was not declared strictly before the judged dataset build, details[0] is a ProtocolAfterDataDetail (type: precondition_failure, reason: protocol_after_data, protocol_id, declared_at, dataset_id, dataset_created_at). When another signals evaluation of the model is running (POST /models/\{model_id\}/signals-evaluations), details[0] is \{type: precondition_failure, reason: evaluation_in_progress, report_id\}. A slot-addressed backtest whose slot has no active bundle is failed_precondition with reason: slot_without_active_bundle. For POST /models/\{model_id\}/observation-ablations (WP-M16): another observation ablation of the model running is evaluation_in_progress with its report_id, as above; a model whose config does not consume the elapsed-silence token is failed_precondition with reason: observation_time_model_disabled; a without_token_model_id whose config consumes it is failed_precondition with reason: observation_ablation_twin_consumes_token; a without_token_model_id that is not the model's flag-off twin is failed_precondition with reason: observation_ablation_not_twin; a model or twin whose files are being or were deleted is failed_precondition with reason: model_files_purged (model_id names which, status); naming the model itself or an event model as without_token_model_id is invalid_argument. For POST /evaluations:baseline (WP-M22 req 8), a new evaluation whose runtime estimate exceeds the shared evaluation pool's 6 h deadline is failed_precondition with reason: runtime_budget_exceeded, estimated_seconds, ceiling_seconds, budget_seconds (the declared 45 min target), the shape it was computed from (entity_count, row_count, event_count, label_count, arm_count, comparator_count) and the reference shape.
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 /evaluations/{report_id}​

Get a protocol evaluation

The standard evaluation's index row (a hazard-ablation evaluation is 404 here) plus, once it has succeeded, the stored report verbatim (re-hashed against the recorded fingerprint before it is served, 002 §10 — fail closed): an eval_report.json with verdict and evaluation_basis (model basis) or a baseline_eval_report.json (baseline basis). A row still running after 6 h reads as failed with reason timeout. Another tenant's id is 404 not_found (003 §3). A stored report that fails verification is 400 failed_precondition: reason artifact_fingerprint_mismatch with detail \{kind, uri, expected, actual\} (actual is missing for an absent object), or artifact_malformed with \{kind, uri\} for verified bytes that are not the report document.

Operation ID: getEvaluation · 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
report_idpathyesstringReport id of the evaluation (rpt_).

Responses​

StatusSchemaDescription
200ProofEvaluationDetailThe evaluation.
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 /evaluations/{report_id}:hazard-ablation​

Get a hazard-ablation evaluation

The hazard-ablation evaluation's index row plus, once it has succeeded, its hazard_ablation_report.json (re-hashed against the recorded fingerprint before it is served, 002 §10 — fail closed: a stored report that fails verification is 400 failed_precondition with reason artifact_fingerprint_mismatch or artifact_malformed). A row still running after 6 h reads as failed with reason timeout. A standard evaluation id, or another tenant's, is 404 not_found (003 §3).

Operation ID: getHazardAblationEvaluation · 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
report_idpathyesstringReport id of the hazard-ablation evaluation (rpt_).

Responses​

StatusSchemaDescription
200HazardAblationEvaluationDetailThe hazard-ablation evaluation.
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 /evaluations:baseline​

Run the protocol's baselines before any model exists

Prospect mode (WP-M22): runs the protocol's safeguard arms and comparators on a dataset build and records a https://spec.tessera.dev/schemas/baseline_eval_report.json report whose verdict is bar_only (the model is absent). Returns 202 with the evaluation's index row (basis: baseline_eval). Protocol-first: the protocol must have been declared strictly before the build (protocol_after_data otherwise). A hazard-ablation protocol id (WP-M17) is 404 not_found here. An identical request returns the existing evaluation. A new evaluation gets a runtime estimate from the declared 45 min target (req 8); it is refused, with the estimate, only when the estimate exceeds the shared pool's 6 h deadline (runtime_budget_exceeded). An admitted run is never stopped by its estimate: it runs under that same deadline, and a row still running one deadline window after its last update reads failed / timeout.

Operation ID: createBaselineEvaluation · 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​

BaselineEvaluationCreateRequest

Responses​

StatusSchemaDescription
202ProofEvaluationThe evaluation's index row: a new acceptance, or the identical existing evaluation (same report_id, its current status; the createDatasetBuild idempotency precedent).
400ErrorEnvelope400 for the proof create operations (WP-M20/WP-M22), in the 003 §1 envelope: invalid_argument, or failed_precondition. When the protocol was not declared strictly before the judged dataset build, details[0] is a ProtocolAfterDataDetail (type: precondition_failure, reason: protocol_after_data, protocol_id, declared_at, dataset_id, dataset_created_at). When another signals evaluation of the model is running (POST /models/\{model_id\}/signals-evaluations), details[0] is \{type: precondition_failure, reason: evaluation_in_progress, report_id\}. A slot-addressed backtest whose slot has no active bundle is failed_precondition with reason: slot_without_active_bundle. For POST /models/\{model_id\}/observation-ablations (WP-M16): another observation ablation of the model running is evaluation_in_progress with its report_id, as above; a model whose config does not consume the elapsed-silence token is failed_precondition with reason: observation_time_model_disabled; a without_token_model_id whose config consumes it is failed_precondition with reason: observation_ablation_twin_consumes_token; a without_token_model_id that is not the model's flag-off twin is failed_precondition with reason: observation_ablation_not_twin; a model or twin whose files are being or were deleted is failed_precondition with reason: model_files_purged (model_id names which, status); naming the model itself or an event model as without_token_model_id is invalid_argument. For POST /evaluations:baseline (WP-M22 req 8), a new evaluation whose runtime estimate exceeds the shared evaluation pool's 6 h deadline is failed_precondition with reason: runtime_budget_exceeded, estimated_seconds, ceiling_seconds, budget_seconds (the declared 45 min target), the shape it was computed from (entity_count, row_count, event_count, label_count, arm_count, comparator_count) and the reference shape.
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 /evaluations:hazard-ablation​

Evaluate a model against a hazard-ablation protocol

Grades a model with hazard heads (WP-M17 req 7c) against its hazard-ablation protocol and records a https://spec.tessera.dev/schemas/hazard_ablation_report.json report. twin_model_id names the model trained on the flag-off twin of the model's hazard dataset (the identical build request without hazard; the models identical except the hazard heads). Returns 202 with the evaluation's index row (basis: model_eval). The model's dataset must carry exactly the protocol's hazard config (hazard_protocol_mismatch), the twin must be its flag-off twin (hazard_twin_mismatch), both models must have pinned eval reports (hazard_not_evaluated, hazard_twin_not_evaluated) and the protocol must have been declared strictly before the hazard dataset (protocol_after_data): all 400 failed_precondition. A standard protocol id is 404 not_found here. An identical request returns the existing evaluation. The latest succeeded evaluation of a model is the verdict POST /models/\{model_id\}/bundles reads for hazard.enabled.

Operation ID: createHazardAblationEvaluation · 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​

HazardAblationEvaluationCreateRequest

Responses​

StatusSchemaDescription
202ProofEvaluationThe evaluation's index row: a new acceptance, or the identical existing evaluation (same report_id, its current status).
400ErrorEnvelope400 for the proof create operations (WP-M20/WP-M22), in the 003 §1 envelope: invalid_argument, or failed_precondition. When the protocol was not declared strictly before the judged dataset build, details[0] is a ProtocolAfterDataDetail (type: precondition_failure, reason: protocol_after_data, protocol_id, declared_at, dataset_id, dataset_created_at). When another signals evaluation of the model is running (POST /models/\{model_id\}/signals-evaluations), details[0] is \{type: precondition_failure, reason: evaluation_in_progress, report_id\}. A slot-addressed backtest whose slot has no active bundle is failed_precondition with reason: slot_without_active_bundle. For POST /models/\{model_id\}/observation-ablations (WP-M16): another observation ablation of the model running is evaluation_in_progress with its report_id, as above; a model whose config does not consume the elapsed-silence token is failed_precondition with reason: observation_time_model_disabled; a without_token_model_id whose config consumes it is failed_precondition with reason: observation_ablation_twin_consumes_token; a without_token_model_id that is not the model's flag-off twin is failed_precondition with reason: observation_ablation_not_twin; a model or twin whose files are being or were deleted is failed_precondition with reason: model_files_purged (model_id names which, status); naming the model itself or an event model as without_token_model_id is invalid_argument. For POST /evaluations:baseline (WP-M22 req 8), a new evaluation whose runtime estimate exceeds the shared evaluation pool's 6 h deadline is failed_precondition with reason: runtime_budget_exceeded, estimated_seconds, ceiling_seconds, budget_seconds (the declared 45 min target), the shape it was computed from (entity_count, row_count, event_count, label_count, arm_count, comparator_count) and the reference shape.
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}/card/pre-registered-evaluation​

Get a model card's pre-registered evaluation section

The model card's pre-registered evaluation section (https://spec.tessera.dev/schemas/pre_registered_evaluation.json): every succeeded standard-protocol evaluation of the model (never a WP-M17 hazard-ablation evaluation), newest first and cursor-paginated (003 §1), with the protocol fingerprint, verdict and evaluation basis copied verbatim from the stored report after re-hashing it against its recorded fingerprint (002 §10). A model with no succeeded protocol evaluation returns status: not_available. A report whose bytes no longer match fails the read closed, as GET /models/\{model_id\}/card does. A stored report that fails verification is 400 failed_precondition: reason artifact_fingerprint_mismatch with detail \{kind, uri, expected, actual\} (actual is missing for an absent object), or artifact_malformed with \{kind, uri\} for verified bytes that are not the report document. Another tenant's model id is 404 not_found (003 §3).

Operation ID: getModelPreRegisteredEvaluation · 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).
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
200PreRegisteredEvaluationThe pre-registered evaluation section.
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 /models/{model_id}/observation-ablations​

Evaluate a model with the observation-time ablation evidence

WP-M16 req 7 enablement evidence. Launches the model's evaluation Job with one extra option: also produce the report's observation_time_ablation evidence against without_token_model_id, the model's flag-off twin (trained on the flag-off twin dataset build with identical settings except observation_time). Everything else is THE default evaluation of the model (same seed semantics, baselines and signals included), so the gates G1–G6, the label metrics and the baselines are computed as for the default evaluation; the report additionally carries the top-level observation_time_ablation block. That evidence grades four arms (the with-token model, the without-token twin and two internal quality safeguard arms) at the identical evaluation points (the flag-on dataset's test-split event and as-of targets) with the same metric implementations, and recommends enablement only when every gating label is non-regressing and the with-token run passes G1–G6. Returns 202 with the ablation (status: running); poll GET /models/\{model_id\}/observation-ablations/\{report_id\}. When it succeeds, the report becomes the model's evaluation of record (GET /models/\{model_id\}/eval-report serves it), so POST /models/\{model_id\}/bundles with observation_time.enabled: true is created without an observation finding when the evidence recommends enablement (recommend_enable); otherwise it reports the finding for the user to acknowledge (ERRATA 2026-10-15). Bundles created before keep their pins. Refusals are typed: a model that does not consume the token, or a without_token_model_id that does, is 400 failed_precondition with a reason detail (see the 400 response); naming the model itself or an event model is 400 invalid_argument; a without_token_model_id of another tenant or environment is 404 not_found. A named model that is not the twin (other builds, or settings beyond observation_time) is refused before any launch: 400 failed_precondition with detail reason: observation_ablation_not_twin (the evaluation Job checks the pairing again before any compute). A model whose files are being or were deleted (WP-O6 retention) is 400 failed_precondition with detail reason: model_files_purged, model_id and status; this applies to the model and to the without_token_model_id alike (the detail's model_id names which), since the ablation reads both. One observation ablation of a model runs at a time: a create while another is running is 400 failed_precondition with detail reason: evaluation_in_progress (and that ablation's report_id). An identical request returns a running ablation as it is, relaunches a failed one, and makes a succeeded one the model's evaluation of record again (no new Job). The model id of another tenant (or environment) is 404 not_found.

Operation ID: createModelObservationAblation · 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.
model_idpathyesstringThe with-token model (mdl_ ULID, 002 §1): a model whose config consumes the elapsed-silence token (observation_time).

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​

ModelObservationAblationRequest

Responses​

StatusSchemaDescription
202ModelObservationAblationThe observation ablation: a new launch, or the identical existing ablation in its current state.
400ErrorEnvelope400 for the proof create operations (WP-M20/WP-M22), in the 003 §1 envelope: invalid_argument, or failed_precondition. When the protocol was not declared strictly before the judged dataset build, details[0] is a ProtocolAfterDataDetail (type: precondition_failure, reason: protocol_after_data, protocol_id, declared_at, dataset_id, dataset_created_at). When another signals evaluation of the model is running (POST /models/\{model_id\}/signals-evaluations), details[0] is \{type: precondition_failure, reason: evaluation_in_progress, report_id\}. A slot-addressed backtest whose slot has no active bundle is failed_precondition with reason: slot_without_active_bundle. For POST /models/\{model_id\}/observation-ablations (WP-M16): another observation ablation of the model running is evaluation_in_progress with its report_id, as above; a model whose config does not consume the elapsed-silence token is failed_precondition with reason: observation_time_model_disabled; a without_token_model_id whose config consumes it is failed_precondition with reason: observation_ablation_twin_consumes_token; a without_token_model_id that is not the model's flag-off twin is failed_precondition with reason: observation_ablation_not_twin; a model or twin whose files are being or were deleted is failed_precondition with reason: model_files_purged (model_id names which, status); naming the model itself or an event model as without_token_model_id is invalid_argument. For POST /evaluations:baseline (WP-M22 req 8), a new evaluation whose runtime estimate exceeds the shared evaluation pool's 6 h deadline is failed_precondition with reason: runtime_budget_exceeded, estimated_seconds, ceiling_seconds, budget_seconds (the declared 45 min target), the shape it was computed from (entity_count, row_count, event_count, label_count, arm_count, comparator_count) and the reference shape.
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}/observation-ablations/{report_id}​

Get a model's observation-time ablation

One observation ablation's current state, settled on read: succeeded once its report is recorded (with gates_passed and the evidence's recommend_enable), failed with a typed failure_reason when the Job failed (job_failed, job_deadline_exceeded), completed without a report (report_missing), never appeared (job_missing), could not be launched (launch_failed) or outlived the evaluation timeout (timeout), and running otherwise. Another tenant's ablation, or one of another model, is 404 not_found. A model whose files are being or were deleted (WP-O6 retention) is 400 failed_precondition with detail reason: model_files_purged, model_id and status.

Operation ID: getModelObservationAblation · 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).
report_idpathyesstringReport id of the observation ablation (rpt_ ULID, 002 §1).

Responses​

StatusSchemaDescription
200ModelObservationAblationThe observation ablation.
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 /models/{model_id}/signals-evaluations​

Evaluate a model with prediction evidence or a peer frame

WP-M18 evidence enablement. Launches the model's evaluation Job with the requested behavioral-signals options: evidence (per-prediction top-k transition and attribute evidence) and/or an attribute peer_frame (surprise calibrated against the entity's peers). At least one must be enabled (else 400 invalid_argument); the peer attribute must be a contracted categorical feature of an included event type. Everything else is the model's default evaluation (same seed, baselines, the safeguard arms and signals included: the arms feed G1's competitiveness check, WP-M26), so the gates G1–G6, the label metrics and the baselines equal the default evaluation's; only the report's signals block (its config and the evidence references of the calibration artifact) differs. Returns 202 with the evaluation (status: running); poll GET /models/\{model_id\}/signals-evaluations/\{report_id\}. When it succeeds, the report becomes the model's evaluation of record (GET /models/\{model_id\}/eval-report serves it), and POST /models/\{model_id\}/bundles with signals.enabled: true copies its signals.config (including evidence and peer_frame) into the bundle's runtime.signals. Bundles created before keep their pins and runtime unchanged. One signals evaluation of a model runs at a time: a create while another is running is 400 failed_precondition with detail reason: evaluation_in_progress (and that evaluation's report_id). An identical request returns a running evaluation as it is, relaunches a failed one, and makes a succeeded one the model's evaluation of record again (no new Job). The model id of another tenant (or environment) is 404 not_found.

Operation ID: createModelSignalsEvaluation · 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.
model_idpathyesstringModel version id (mdl_ ULID, 002 §1).

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​

ModelSignalsEvaluationRequest

Responses​

StatusSchemaDescription
202ModelSignalsEvaluationThe signals evaluation: a new launch, or the identical existing evaluation in its current state.
400ErrorEnvelope400 for the proof create operations (WP-M20/WP-M22), in the 003 §1 envelope: invalid_argument, or failed_precondition. When the protocol was not declared strictly before the judged dataset build, details[0] is a ProtocolAfterDataDetail (type: precondition_failure, reason: protocol_after_data, protocol_id, declared_at, dataset_id, dataset_created_at). When another signals evaluation of the model is running (POST /models/\{model_id\}/signals-evaluations), details[0] is \{type: precondition_failure, reason: evaluation_in_progress, report_id\}. A slot-addressed backtest whose slot has no active bundle is failed_precondition with reason: slot_without_active_bundle. For POST /models/\{model_id\}/observation-ablations (WP-M16): another observation ablation of the model running is evaluation_in_progress with its report_id, as above; a model whose config does not consume the elapsed-silence token is failed_precondition with reason: observation_time_model_disabled; a without_token_model_id whose config consumes it is failed_precondition with reason: observation_ablation_twin_consumes_token; a without_token_model_id that is not the model's flag-off twin is failed_precondition with reason: observation_ablation_not_twin; a model or twin whose files are being or were deleted is failed_precondition with reason: model_files_purged (model_id names which, status); naming the model itself or an event model as without_token_model_id is invalid_argument. For POST /evaluations:baseline (WP-M22 req 8), a new evaluation whose runtime estimate exceeds the shared evaluation pool's 6 h deadline is failed_precondition with reason: runtime_budget_exceeded, estimated_seconds, ceiling_seconds, budget_seconds (the declared 45 min target), the shape it was computed from (entity_count, row_count, event_count, label_count, arm_count, comparator_count) and the reference shape.
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}/signals-evaluations/{report_id}​

Get a model's signals evaluation

One signals evaluation's current state, settled on read: succeeded once its report is recorded (with gates_passed), failed with a typed failure_reason when the Job failed (job_failed, job_deadline_exceeded), completed without a report (report_missing), never appeared (job_missing), could not be launched (launch_failed) or outlived the evaluation timeout (timeout), and running otherwise. Another tenant's evaluation, or one of another model, is 404 not_found.

Operation ID: getModelSignalsEvaluation · 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).
report_idpathyesstringReport id of the signals evaluation (rpt_ ULID, 002 §1).

Responses​

StatusSchemaDescription
200ModelSignalsEvaluationThe signals evaluation.
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 /protocols​

List protocols

Standard protocols of the resolved project + environment, newest first (cursor pagination, 003 §1). Hazard-ablation protocols (WP-M17) are a separate resource and are never listed here.

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

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
200ProtocolPagePage of protocols, 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 /protocols​

Declare a protocol

Declares an immutable evaluation protocol (WP-M20 req 2) in one call: labels, metrics, safeguard arms, comparators, per-metric success margins, the inline banding policy and the provenance claim. The server mints a prt_ ULID, canonical-JSON fingerprints the declared content and records it with its protocol.create audit row in one transaction; declared_at is that row's server-clock instant. There is no update or delete: supersede a protocol by declaring a new one. Declare the protocol before building the dataset it will judge: evaluations, baseline runs and backtests of a dataset build whose manifest created_at is not strictly later than declared_at fail with 400 failed_precondition (protocol_after_data). Unknown labels, metrics, arms or comparators, a protocol with neither an arm nor a comparator, and detection_quality entries that name an undeclared label or repeat a (label, metric) pair are 400 invalid_argument.

Operation ID: createProtocol · 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​

ProtocolCreateRequest

Responses​

StatusSchemaDescription
201ProtocolThe declared protocol.
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 /protocols/{protocol_id}​

Get a protocol

One standard protocol, verbatim as declared, with its fingerprint, declared_at and audit id (a hazard-ablation protocol id is 404 here). Another tenant's prt_ id is indistinguishable from a missing one (404 not_found, 003 §3).

Operation ID: getProtocol · 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
protocol_idpathyesstringProtocol id (prt_ ULID, 002 §1).

Responses​

StatusSchemaDescription
200ProtocolThe protocol.
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 /protocols:hazard-ablation​

Declare a hazard-ablation protocol

Declares an immutable hazard-ablation protocol (WP-M17 req 7c) in one call: the hazard config it covers (targets and horizons), the metrics (auc, brier), the arms the model with hazard heads must beat (model_without_hazard: the model trained on the flag-off twin build; bgnbd_gg: the WP-M19 internal event-timing safeguard), per-metric margins and the provenance claim. Stored with the WP-M20 protocols under kind: hazard_ablation and never listed or served by the standard protocol reads. The server mints a prt_ ULID, canonical-JSON fingerprints the declared content and records it with its protocol.create audit row in one transaction; declared_at is that row's server-clock instant. Declare it before building the hazard dataset it will judge: an evaluation of a model whose dataset manifest created_at is not strictly later than declared_at fails with 400 failed_precondition (protocol_after_data). Both metrics and both arms are fixed content (omitted declares them); a subset, unknown metrics or arms, margins for undeclared metrics, an invalid hazard config, an unknown or non-derived target label, or a label whose rule horizon is not on the hazard grid are 400 invalid_argument. The bootstrap seed is declared here (omitted: derived from the declared content), never per evaluation.

Operation ID: createHazardAblationProtocol · 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​

HazardAblationProtocolCreateRequest

Responses​

StatusSchemaDescription
201HazardAblationProtocolThe declared hazard-ablation protocol.
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.