Skip to main content

datasets

GET /datasets​

List dataset builds

Dataset builds of the resolved project + environment, newest first (cursor pagination, 003 §1). List entries omit manifest and violation_report; fetch one build for those. Optional filters combine with AND and apply before page-size limits. Date bounds select created_at instants; a lower bound greater than or equal to the upper bound is invalid_argument. Restart pagination when filters change. Omitting filters preserves existing list behavior and the response representation. Annotations (TES-034) appear only with the explicit include_annotations=true opt-in; default responses never gain annotation or reusable-configuration fields.

Operation ID: listDatasets · 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
created_at_gtequerynostringInclusive created_at lower bound (RFC3339 instant, normalized to UTC microseconds). If created_at_lt is supplied, this must precede it; otherwise return invalid_argument using the standard error envelope.
created_at_ltquerynostringExclusive created_at upper bound (RFC3339 instant, normalized to UTC microseconds). If created_at_gte is supplied, this must follow it; otherwise return invalid_argument using the standard error envelope.
cursorquerynostringOpaque pagination cursor from a previous response's next_cursor.
include_annotationsquerynobooleanExplicitly opt into each item's annotations (TES-034). Omitted or false preserves the existing representation without annotations; true adds them to every item, including never-annotated items (revision 0). Retain this option on subsequent cursor requests.
label_idquerynostringExact membership in the resource's stored label-ID set. Empty-label resources do not match. A missing or out-of-scope ID produces an empty page without resolving another tenant's label. Combine with other filters before cursor pagination.
limitquerynointegerPage size (cursor pagination, 003 §1). Maximum 200.
statusquerynostringExact dataset-build lifecycle status; applied before cursor pagination.
tagquerynostringExact whole-tag membership in the resource's annotation tags (TES-034; see ExperimentTag). Never a substring or serialized-text match. Resources without annotations do not match; an unused tag produces an empty page. Combine with other filters (AND) before cursor pagination. A malformed tag is invalid_argument.

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
200DatasetBuildPagePage of dataset builds, 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 /datasets​

Start a dataset build

Resolves and pins every input (WP-D3 req 2) — event-store snapshot (created + pinned when snapshot_id is omitted), approved contract (contract_version omitted → current approved; none approved → 400 failed_precondition), current leakage policy, each label definition plus, for label_table labels, its label-store manifest — computes the content-addressed build fingerprint, persists the build record (queued) and launches one GKE Job on the cpu-batch pool (Spot-tolerant). A request resolving to an existing fingerprint is idempotent: queued/running/succeeded builds return their dataset_id unchanged, failed builds relaunch under the same dataset_id (stage markers govern resumption) while their snapshot is not yet released, aborted_leakage builds return the aborted record without relaunch. A failed build holds its snapshot only while its own files exist: once the entity-deletion worker deleted them and released the snapshot (a read releases it only after that), that snapshot protects nothing and a request naming it is 400 failed_precondition with details[0].reason = snapshot_expired (preview_snapshot_expired for an eligibility-preview snapshot); create a new build (omit snapshot_id). Every label's entity_type must equal the request's (400 invalid_argument). Optional expected_fingerprint (TES-034 exact reuse) is a precondition checked after resolution and before deduplication, persistence or launch: a different resolved fingerprint returns 400 failed_precondition whose pin_drift details name every drifted input, and nothing is created or launched. A named snapshot_id that is unpinned and expired, or expires within 15 minutes, or whose protection has ended (released with the failed build that pinned it, or by an erasure as a pin that no holder names), is 400 failed_precondition with details[0].reason = snapshot_expired, before anything is pinned (WP-O7). Optional temporal_holdout (WP-M26) holds the last part of the time range out of the train and validation splits and grades the test split only on events at or after its start (an out-of-time, out-of-entity holdout); it is request-only and is checked against window.time_range (400 invalid_argument unless window.time_range.start \< start \<= window.time_range.end; combined with an enabled observation_time, 400 invalid_argument with details[0].reason = temporal_holdout_observation_time_unsupported). A holdout build cannot be previewed, so expected_base_fingerprint carries the drift protection of expected_fingerprint for it: the build_fingerprint that previewDatasetEligibility returns for the same request WITHOUT temporal_holdout; it is valid only together with temporal_holdout and explicit snapshot_id and contract_version (alone: 400 invalid_argument, details[0].reason = expected_base_fingerprint_requires_temporal_holdout), a mismatch is the same pin_drift 400 failed_precondition, and it is never normalized, fingerprinted, stored or echoed. The finite-export censor clock of derived labels (WP-M26) is min(snapshot time, the greatest matching event timestamp); a build records it in the manifest censor_clock, and GET /datasets/\{dataset_id\}/holdout reads the holdout and the clock.

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

DatasetBuildCreateRequest

Responses​

StatusSchemaDescription
202DatasetBuildThe dataset build record (new or idempotent existing).
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 /datasets/{dataset_id}​

Get a dataset build

Status (queued | running | failed | aborted_leakage | succeeded) + current stage, plus the manifest.json document (https://spec.tessera.dev/schemas/dataset_manifest.json) once the build succeeded and the typed violation report — populated for aborted_leakage builds (in the manifest position, WP-D3 req 4) and embedded in the manifest (warn-level entries) for succeeded ones. Another tenant's dataset id is indistinguishable from a missing one (404 not_found, 003 §3).

Operation ID: getDataset · 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
dataset_idpathyesstringDataset id (ds_ ULID, 002 §1).

Responses​

StatusSchemaDescription
200DatasetBuildThe dataset build.
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 /datasets/{dataset_id}/annotations​

Get a dataset build's annotations

The build's human display name and tags (TES-034). A build that was never annotated returns revision 0 with a null name and no tags. Another tenant's dataset id is indistinguishable from a missing one (404 not_found, 003 §3).

Operation ID: getDatasetAnnotations · 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
dataset_idpathyesstringDataset id (ds_ ULID, 002 §1).

Responses​

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

PATCH /datasets/{dataset_id}/annotations​

Update a dataset build's annotations

Sets or clears the build's display name and replaces its tag set (TES-034). Absent fields are unchanged. Annotations are stored apart from the build: its request, pins, fingerprint, deduplication, lifecycle updated_at and creation provenance stay byte-identical. A request that changes nothing returns the current annotations without a new revision or audit event; an effective change increments revision by one and records one dataset.annotate audit event in the same transaction. expected_revision makes the update conditional (400 failed_precondition, reason annotation_revision_mismatch, when another change won).

Operation ID: updateDatasetAnnotations · 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
dataset_idpathyesstringDataset id (ds_ ULID, 002 §1).

Request body​

ExperimentAnnotationsUpdate

Responses​

StatusSchemaDescription
200ExperimentAnnotationsThe resulting annotations.
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 /datasets/{dataset_id}/extended-recipe​

Get a dataset build's complete reusable recipe

The complete retained configuration of one build for cloning and exact reuse (WP-M16): getDatasetRecipe plus the options its closed v1 request cannot carry, currently observation_time. Released strict SDK models reject unknown fields in the v1 recipe, so this is an additive operation with its own response schema. request is the build record's stored normalized request (never reconstructed) with the pinned snapshot_id and contract_version and expected_fingerprint = fingerprint; POST it to POST /datasets to reuse the build exactly, or omit snapshot_id and expected_fingerprint to upgrade it with observation_time kept. Any build can be read here; for one without observation time the content equals getDatasetRecipe. Read-only: nothing is pinned, created or launched. Another tenant's dataset id is indistinguishable from a missing one (404 not_found, 003 §3). The response keeps its released shape: request is DatasetBuildExtendedReplayRequest, a frozen copy of the DatasetBuildRequest of WP-M16, so a build that used temporal_holdout (WP-M26) is refused with 400 failed_precondition (details[0].reason = temporal_holdout_recipe_unsupported); read it through getDatasetHoldoutRecipe. A build that used hazard (WP-M17) is refused the same way (details[0].reason = hazard_recipe_required) rather than answered with a request that would silently rebuild without it; read it through getDatasetHazardRecipe.

Operation ID: getDatasetExtendedRecipe · 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
dataset_idpathyesstringDataset id (ds_ ULID, 002 §1).

Responses​

StatusSchemaDescription
200DatasetBuildExtendedRecipeThe build's complete recipe.
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 /datasets/{dataset_id}/hazard-recipe​

Get a dataset build's recipe including its hazard targets

The complete retained configuration of one build for cloning and exact reuse (WP-M17): getDatasetExtendedRecipe plus the hazard config its frozen request cannot carry. An additive operation with its own response schema (released strict SDK models reject unknown fields in the existing recipes). request is the build record's stored normalized request (never reconstructed) with the pinned snapshot_id and contract_version and expected_fingerprint = fingerprint; POST it to POST /datasets to reuse the build exactly, or omit snapshot_id and expected_fingerprint to upgrade it with observation_time and hazard kept. Any build without temporal_holdout (WP-M26) can be read here; for one without hazard targets the content equals getDatasetExtendedRecipe. A build that used temporal_holdout is refused as by the other recipes (400 failed_precondition, details[0].reason = temporal_holdout_recipe_unsupported); a hazard build never uses it. request echoes the frozen DatasetBuildHazardReplayRequest (the pre-WP-M26 request plus hazard), so no response carries the WP-M26 request-only fields. Read-only: nothing is pinned, created or launched. Another tenant's dataset id is indistinguishable from a missing one (404 not_found, 003 §3).

Operation ID: getDatasetHazardRecipe · 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
dataset_idpathyesstringDataset id (ds_ ULID, 002 §1).

Responses​

StatusSchemaDescription
200DatasetBuildHazardRecipeThe build's complete recipe, hazard targets included.
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 /datasets/{dataset_id}/holdout​

Get a dataset build's holdout and censor clock

The holdout of one build (WP-M26): kind is time_and_entity when the build used temporal_holdout (an out-of-time, out-of-entity test split; start is its normalized start) and entity otherwise (the entity-hash split alone, every build made before WP-M26 included); censor_clock is the derived-label censor clock the build recorded in its manifest (absent for a build made before the WP-M26 builder or one that has not succeeded). models_evaluated counts the distinct models trained on this build (each model version pins the build by its fingerprint) with at least one recorded evaluation report, read from the existing report rows; a re-evaluation or a protocol evaluation of one model counts once and a baseline-first evaluation never counts. Once it exceeds fresh_holdout_recommended_after a fresh holdout is recommended: fresh_holdout_recommended_after is a recommendation shown to the user; nothing refuses an evaluation or a bundle because of it. Read-only. Another tenant's dataset id is indistinguishable from a missing one (404 not_found, 003 §3).

Operation ID: getDatasetHoldout · 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
dataset_idpathyesstringDataset id (ds_ ULID, 002 §1).

Responses​

StatusSchemaDescription
200DatasetHoldoutThe build's holdout.
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 /datasets/{dataset_id}/holdout-recipe​

Get a holdout build's reusable recipe

The complete retained configuration of one build that used temporal_holdout (WP-M26), for cloning and exact reuse: the closed recipes getDatasetRecipe and getDatasetExtendedRecipe cannot carry the field and refuse such a build. request is the build record's stored normalized request (never reconstructed) with the pinned snapshot_id and contract_version and expected_fingerprint = fingerprint; POST it to POST /datasets to reuse the build exactly, or omit snapshot_id and expected_fingerprint to upgrade it with temporal_holdout kept. A build that did not use the field is 400 failed_precondition (details[0].reason = temporal_holdout_not_used): its own recipe reads serve it. Read-only: nothing is pinned, created or launched. Another tenant's dataset id is indistinguishable from a missing one (404 not_found, 003 §3).

Operation ID: getDatasetHoldoutRecipe · 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
dataset_idpathyesstringDataset id (ds_ ULID, 002 §1).

Responses​

StatusSchemaDescription
200DatasetHoldoutRecipeThe holdout build's recipe.
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 /datasets/{dataset_id}/recipe​

Get a dataset build's reusable recipe

The exact retained configuration of one build for cloning (TES-034), read from the build record's stored normalized request and resolved pins (never reconstructed from the abbreviated DatasetBuild representation), plus the versions an explicit upgrade would resolve today. Read-only: nothing is pinned, created or launched. Another tenant's dataset id is indistinguishable from a missing one (404 not_found, 003 §3). The closed v1 request cannot carry observation_time (WP-M16): a build that used it is refused with 400 failed_precondition (details[0].reason = observation_time_extended_recipe_required) rather than answered with a request that would silently rebuild without it; read it through getDatasetExtendedRecipe. A build that used temporal_holdout (WP-M26) is refused the same way with 400 failed_precondition (details[0].reason = temporal_holdout_recipe_unsupported); read its replay request through getDatasetHoldoutRecipe. A build that used hazard (WP-M17) is refused the same way with hazard_recipe_required; read it through getDatasetHazardRecipe.

Operation ID: getDatasetRecipe · 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
dataset_idpathyesstringDataset id (ds_ ULID, 002 §1).

Responses​

StatusSchemaDescription
200DatasetBuildRecipeThe build's recipe.
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 /datasets:eligibility​

Preview dataset eligibility before starting a build

Eligibility preflight for POST /datasets (WP-D3 / WP-U14; audit TES-015; 003 §1 :action convention). Resolves exactly the inputs a build would pin — event-store snapshot, approved contract, current leakage policy, label definitions and label-store manifests — and runs the builder's own extraction, windowing, label masking and support checks over them, WITHOUT creating a build record, launching a Job, writing shards, publishing derived observations or metering. Every count describes the returned snapshot and build_fingerprint. The preview is bounded by a server-side deadline (25 s by default, kept under the load balancer's 30 s): a preview that cannot finish in time answers 503 unavailable with details[0].reason = eligibility_deadline_exceeded and a message asking the caller to narrow the time range or choose fewer event types or one source. When snapshot_id is omitted the preview takes a short-lived, unpinned preview snapshot (reused while no new event batch has been committed); a preview never pins or releases any snapshot. Starting the returned launch_request through POST /datasets pins it as a normal build input. Its expected_fingerprint is the TES-034 exact-reuse receipt: if any input changed the build fails with 400 failed_precondition and pin_drift details, and if the preview snapshot lease expired with details[0].reason = preview_snapshot_expired, and if an erasure or retention was committed after the preview snapshot with details[0].reason = preview_snapshot_superseded — refresh the preview. A preview naming a snapshot_id reads it as it is, but refuses one released with a failed build (400 failed_precondition, details[0].reason = snapshot_expired, or preview_snapshot_expired for an eligibility-preview snapshot), and the launch refuses an unpinned snapshot that expired or expires within 15 minutes, or was released, with details[0].reason = snapshot_expired (WP-O7). A snapshot data file that no longer matches its manifest bytes is refused with details[0].reason = snapshot_file_mismatch. Entities erased since the snapshot was taken are excluded from every count, so a preview never reports their rows. ready means the builder's early checks pass; checks_remaining lists the later build checks and the authorities neither preview nor build verifies today. expected_fingerprint in a preview request is ignored. A request that enables observation_time (WP-M16) is refused with 400 failed_precondition (details[0].reason = observation_time_preview_unsupported): the closed launch_request cannot carry it, and launching it without would silently build without it. Preview the same request without observation_time: the counts describe the base entity windows, which observation time extends with augmented as-of rows but does not change. A request with hazard (WP-M17) is refused before that check, with details[0].reason = hazard_preview_unsupported, for the same reason: preview it without hazard and observation_time. A request that carries temporal_holdout (WP-M26), with or without expected_base_fingerprint, is refused with 400 failed_precondition (details[0].reason = temporal_holdout_preview_unsupported): the closed eligibility mask counts cannot carry the holdout mask reasons, and the closed launch_request cannot carry the field. expected_base_fingerprint without temporal_holdout is 400 invalid_argument (details[0].reason = expected_base_fingerprint_requires_temporal_holdout), checked first. Preview the same request without temporal_holdout and send the returned build_fingerprint as expected_base_fingerprint with the holdout to POST /datasets. The horizon_open counts and the support check use the build's censor clock, min(snapshot time, available_time_ranges.matching_events.end) (WP-M26).

Operation ID: previewDatasetEligibility · 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 never replays a stored response (003 §1): a retry carrying the same Idempotency-Key runs again, against current data.

Request body​

DatasetBuildCreateRequest

Responses​

StatusSchemaDescription
200DatasetEligibilityThe pinned eligibility preview, including any blockers.
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.