labels
GET /labels
List label definitions
Label definitions of the resolved project + environment, newest first (cursor pagination, 003 §1). Archived labels are hidden by default (WP-O4): status=active is implied; pass status=archived or status=all to include them. Unknown status values fail with 400 invalid_argument (deny by default). Pattern labels (WP-C7 v2) are never listed here: their pattern rule does not fit the closed LabelDefinition; GET /pattern-labels lists them.
Operation ID: listLabels · Service: gateway-api
Authentication
apiKey(http (bearer)) — Project API key (003 §2):tsk_live_…ortsk_test_…inAuthorization: Bearer. Scoped to exactly one project + environment; scopes are a subset ofingest,read,admin. Keys are stored hashed and shown once at creation.consoleSession(http (bearer)) — Console session (003 §2): Identity Platform JWT. Data-plane calls addX-Tessera-Project+X-Tessera-Environmentheaders, validated against org membership.
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
cursor | query | no | string | Opaque pagination cursor from a previous response's next_cursor. |
limit | query | no | integer | Page size (cursor pagination, 003 §1). Maximum 200. |
status | query | no | string | Lifecycle filter (WP-O4). Default active — archived labels are hidden from the default list. |
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
| Status | Schema | Description |
|---|---|---|
200 | LabelPage | Page of label definitions. |
default | ErrorEnvelope | Error 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 /labels
Declare a supervision target
Creates a LabelDefinition (002 §6; WP-C5 req 1). Validates the full shape: name pattern, task/classes coherence (classes required, ≥ 2, unique, iff multiclass), maturation_days ≥ 0, entity_type registered in the project, and a source of exactly one kind — label_table sources must reference an existing batch-kind source and name its columns; label_events sources must name a valid event_type + value_attribute; derived sources are validated against derived_outcome_rule.json with template-preset defaulting (WP-C6 reqs 1-2 — churn defaults outcome: absence, conversion/recurrence default presence, recurrence defaults min_count: 2; contradictions are 400 invalid_argument, never silently corrected), require task: binary, bind maturation_days to the rule's horizon_days (defaulted when omitted) and reject the null_semantics opt-in (WP-C6 req 4). The assume_negative_after_maturation opt-in requires guard_min_positive_rate ∈ (0, 1) (400 invalid_argument otherwise). A label_events value_attribute that is role: feature in the current approved contract fails with 400 failed_precondition (reason label_attribute_not_target_only) — labels are targets, never inputs. On success the label's name and value_column/value_attribute are registered into leakage-policy deny-pattern scanning (WP-C5 req 4) so contract inference marks matching attributes target_only.
Operation ID: createLabel · Service: gateway-api
Authentication
apiKey(http (bearer)) — Project API key (003 §2):tsk_live_…ortsk_test_…inAuthorization: Bearer. Scoped to exactly one project + environment; scopes are a subset ofingest,read,admin. Keys are stored hashed and shown once at creation.consoleSession(http (bearer)) — Console session (003 §2): Identity Platform JWT. Data-plane calls addX-Tessera-Project+X-Tessera-Environmentheaders, validated against org membership.
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
Idempotency-Key | header | no | string | Idempotency 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
Responses
| Status | Schema | Description |
|---|---|---|
201 | LabelDefinition | The created label definition. |
default | ErrorEnvelope | Error 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 /labels/{label_id}
Get one label definition
The stored definition. Another tenant's label id is indistinguishable from a missing one (404 not_found, 003 §3). A pattern label (WP-C7 v2) answers 400 failed_precondition, reason pattern_label: read it with GET /pattern-labels/\{label_id\}.
Operation ID: getLabel · Service: gateway-api
Authentication
apiKey(http (bearer)) — Project API key (003 §2):tsk_live_…ortsk_test_…inAuthorization: Bearer. Scoped to exactly one project + environment; scopes are a subset ofingest,read,admin. Keys are stored hashed and shown once at creation.consoleSession(http (bearer)) — Console session (003 §2): Identity Platform JWT. Data-plane calls addX-Tessera-Project+X-Tessera-Environmentheaders, validated against org membership.
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
label_id | path | yes | string | Label id (lbl_ ULID, 002 §1). |
Responses
| Status | Schema | Description |
|---|---|---|
200 | LabelDefinition | The label definition. |
default | ErrorEnvelope | Error 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. |
DELETE /labels/{label_id}
Archive a label definition
Soft-archives the label (WP-O4): sets status=archived + archived_at, hides it from the default GET /labels list and excludes it from FUTURE dataset builds. The append-only observation store is retained untouched, and datasets that already pinned the label's fingerprint are unaffected (WP-C5 R10-11). GET /labels/\{label_id\} keeps resolving the archived label; POST /labels/\{label_id\}:restore un-archives it. Idempotent: re-archiving returns 204 without a duplicate audit event.
Operation ID: deleteLabel · Service: gateway-api
Authentication
apiKey(http (bearer)) — Project API key (003 §2):tsk_live_…ortsk_test_…inAuthorization: Bearer. Scoped to exactly one project + environment; scopes are a subset ofingest,read,admin. Keys are stored hashed and shown once at creation.consoleSession(http (bearer)) — Console session (003 §2): Identity Platform JWT. Data-plane calls addX-Tessera-Project+X-Tessera-Environmentheaders, validated against org membership.
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
label_id | path | yes | string | Label id (lbl_ ULID, 002 §1). |
Responses
| Status | Schema | Description |
|---|---|---|
204 | — | Label archived (or already archived). |
default | ErrorEnvelope | Error 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 /labels/{label_id}
Update a label definition
Allows only description-class metadata, maturation_days, null_semantics, backdating_limit_days, and source column renames (same source kind and referenced source/event type; WP-C5 req 3). name, entity_type, and task are immutable after the first ingested observation (400 failed_precondition); any field outside the allowed set fails 400 invalid_argument. Renaming value_column/value_attribute re-registers the deny patterns and re-checks the approved contract (WP-C5 req 4). Derived labels (WP-C6 req 5): the whole rule may be replaced until the first successful materialization is recorded — afterwards it is immutable (400 failed_precondition, detail derived_rule_frozen; a changed rule is a different outcome — create a new label); PATCHing maturation_days on a derived label is 400 invalid_argument (bound to horizon_days). A pattern label (WP-C7 v2) answers 400 failed_precondition, reason pattern_label: update it with PATCH /pattern-labels/\{label_id\}.
Operation ID: updateLabel · Service: gateway-api
Authentication
apiKey(http (bearer)) — Project API key (003 §2):tsk_live_…ortsk_test_…inAuthorization: Bearer. Scoped to exactly one project + environment; scopes are a subset ofingest,read,admin. Keys are stored hashed and shown once at creation.consoleSession(http (bearer)) — Console session (003 §2): Identity Platform JWT. Data-plane calls addX-Tessera-Project+X-Tessera-Environmentheaders, validated against org membership.
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
label_id | path | yes | string | Label id (lbl_ ULID, 002 §1). |
Request body
Responses
| Status | Schema | Description |
|---|---|---|
200 | LabelDefinition | The updated label definition. |
default | ErrorEnvelope | Error 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 /labels/{label_id}/provenance
Get where a label came from
WP-C10 req 6. A label a domain pack install created from a recipe carries origin: \{pack, version, pack_fingerprint, install_id\} — provenance metadata only, never part of the 002 §6 definition or its fingerprint. Every other label answers origin: null. It is a separate read so the closed LabelDefinition that installed SDKs validate never grows (specs/ERRATA.md). Archived labels stay resolvable by id; another tenant's label is indistinguishable from a missing one (404 not_found, 003 §3).
Operation ID: getLabelProvenance · Service: gateway-api
Authentication
apiKey(http (bearer)) — Project API key (003 §2):tsk_live_…ortsk_test_…inAuthorization: Bearer. Scoped to exactly one project + environment; scopes are a subset ofingest,read,admin. Keys are stored hashed and shown once at creation.consoleSession(http (bearer)) — Console session (003 §2): Identity Platform JWT. Data-plane calls addX-Tessera-Project+X-Tessera-Environmentheaders, validated against org membership.
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
label_id | path | yes | string | Label id (lbl_ ULID, 002 §1). |
Responses
| Status | Schema | Description |
|---|---|---|
200 | LabelProvenance | The label's provenance. |
default | ErrorEnvelope | Error 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 /labels/{label_id}/stats
Per-label support stats
Support statistics for one label (WP-C5 req 12), served entirely from the Cloud SQL rollup maintained incrementally at ingestion — zero label-store (GCS) reads per request. maturation_coverage evaluates the label's current maturation_days at read time (partially matured days count as immature — conservative); weekly buckets are keyed by the ISO-week Monday date. The task-specific block is positive_rate (binary) | class_counts (multiclass) | value_quantiles (regression).
Operation ID: getLabelStats · Service: gateway-api
Authentication
apiKey(http (bearer)) — Project API key (003 §2):tsk_live_…ortsk_test_…inAuthorization: Bearer. Scoped to exactly one project + environment; scopes are a subset ofingest,read,admin. Keys are stored hashed and shown once at creation.consoleSession(http (bearer)) — Console session (003 §2): Identity Platform JWT. Data-plane calls addX-Tessera-Project+X-Tessera-Environmentheaders, validated against org membership.
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
label_id | path | yes | string | Label id (lbl_ ULID, 002 §1). |
Responses
| Status | Schema | Description |
|---|---|---|
200 | LabelStats | The label's support stats. |
default | ErrorEnvelope | Error 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 /labels/{label_id}:restore
Restore an archived label definition
Un-archives the label (WP-O4; 003 §1 :action): sets status=active, clears archived_at and returns the label to the default list and to future dataset assembly. Restoring an already-active label is a no-op success (200). A pattern label (WP-C7 v2) answers 400 failed_precondition, reason pattern_label: restore it with POST /pattern-labels/\{label_id\}:restore.
Operation ID: restoreLabel · Service: gateway-api
Authentication
apiKey(http (bearer)) — Project API key (003 §2):tsk_live_…ortsk_test_…inAuthorization: Bearer. Scoped to exactly one project + environment; scopes are a subset ofingest,read,admin. Keys are stored hashed and shown once at creation.consoleSession(http (bearer)) — Console session (003 §2): Identity Platform JWT. Data-plane calls addX-Tessera-Project+X-Tessera-Environmentheaders, validated against org membership.
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
Idempotency-Key | header | no | string | Idempotency 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. |
label_id | path | yes | string | Label id (lbl_ 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.
Responses
| Status | Schema | Description |
|---|---|---|
200 | LabelDefinition | The restored (or already active) label definition. |
default | ErrorEnvelope | Error 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 /labels:preview
Dry-run an unsaved derived label rule
Derived-rule preview (WP-C6 R18; 003 §1 :action convention; interface vendored ahead of the WP-C6 implementation — see specs/ERRATA.md). Accepts an UNSAVED \{entity_type, task, source: \{kind: "derived", rule\}\} payload (same validation as POST /labels for derived sources, nothing persisted), reads the newest N days of that type's events, samples up to sample_entities entities of that type, grades their anchors in those days exactly as the WP-C6 materializer would with snapshot_time = now and the censor clock min(now, the newest event of that type in the store) (WP-M26: anchors whose horizon ends after the data are censored, never graded), and returns anchor / observation counts plus ≤ 10 examples that include each outcome present (positive, negative, censored). N is 2 × horizon_days + 1 UTC days (at least 28) back from the newest event of the requested entity type, never later than today. The sample is spread evenly, by a hash of the entity key, over every entity with an event on the window's days up to and including the UTC day that holds the censor clock − horizon_days, so every anchor with a closed horizon belongs to a candidate: it is the sample_entities candidates with the smallest key hash, however many candidates there are. Entities are not taken from the newest day first, because those are the ones still active. When no such day of the window holds an entity of the type, the entities found first from the newest day are sampled. The window steps further back only until sample_entities entities are found (candidates, when such a day exists), and stops early at its read budget (512 data files, 32 MiB or 12 s of reading). The counts cover only that window and every example comes from it; whole-history counts come from the dataset build. Each anchor in the window gets the same value as a full-history build at the preview's snapshot time (TES-031). When the window holds no entity of the type, warnings includes entity_type_has_no_recent_events (never rule_matches_nothing_in_sample). When the 12 s read limit stops the window early, warnings includes preview_read_limit_reached: the counts then cover fewer days, possibly none whose horizons have closed (every sampled anchor censored), and with nothing sampled it replaces entity_type_has_no_recent_events, since the unread older days may hold the type. A preview that cannot finish within 25 s fails with 503 unavailable (details[0].reason: label_preview_deadline_exceeded) and a request id; at most two previews run per gateway process, and another one gets 503 unavailable (preview_capacity_exhausted) with Retry-After. A client that disconnects stops the preview. Entity ids only ever appear as entity_hash (002 §3). Read-only; when at least one sampled anchor's horizon has closed (observations > 0) and the rule matches zero future events across the sample, the preview returns warnings: ["rule_matches_nothing_in_sample"] rather than an error (the WP-C6 R13 build-time guard remains authoritative). When no anchor in the sample has a closed horizon (observations 0), the rule was not judged and no rule warning is returned; the dataset build's label support gives the rate. An entity whose erasure has begun is left out and not replaced, so sampled_entities can be smaller than sample_entities. Its events never set the censor clock either: when the erasure of every entity holding the clock (every one the lookup checked) begins during the preview, the preview fails with 503 unavailable (details[0].reason: label_preview_clock_entity_erased) and Retry-After; retry it. Consumed by the WP-U3 label wizard's live preview — the console never evaluates derived-rule predicates itself.
Operation ID: previewLabel · Service: gateway-api
Authentication
apiKey(http (bearer)) — Project API key (003 §2):tsk_live_…ortsk_test_…inAuthorization: Bearer. Scoped to exactly one project + environment; scopes are a subset ofingest,read,admin. Keys are stored hashed and shown once at creation.consoleSession(http (bearer)) — Console session (003 §2): Identity Platform JWT. Data-plane calls addX-Tessera-Project+X-Tessera-Environmentheaders, validated against org membership.
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
Idempotency-Key | header | no | string | Idempotency 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
Responses
| Status | Schema | Description |
|---|---|---|
200 | LabelPreviewResponse | The dry-run evaluation over the sampled entities. |
default | ErrorEnvelope | Error 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 /pattern-labels
List pattern label definitions
Derived labels whose outcome is a behavioral pattern (WP-C7 v2: predicate.kind: pattern) of the resolved project + environment, newest first (cursor pagination, 003 §1). GET /labels never lists them: its closed LabelDefinition cannot carry a pattern predicate. Archived labels are hidden by default; status=archived|all includes them (WP-O4). Unknown status values fail with 400 invalid_argument.
Operation ID: listPatternLabels · Service: gateway-api
Authentication
apiKey(http (bearer)) — Project API key (003 §2):tsk_live_…ortsk_test_…inAuthorization: Bearer. Scoped to exactly one project + environment; scopes are a subset ofingest,read,admin. Keys are stored hashed and shown once at creation.consoleSession(http (bearer)) — Console session (003 §2): Identity Platform JWT. Data-plane calls addX-Tessera-Project+X-Tessera-Environmentheaders, validated against org membership.
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
cursor | query | no | string | Opaque pagination cursor from a previous response's next_cursor. |
limit | query | no | integer | Page size (cursor pagination, 003 §1). Maximum 200. |
status | query | no | string | Lifecycle filter (WP-O4). Default active. |
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
| Status | Schema | Description |
|---|---|---|
200 | PatternLabelPage | Page of pattern label definitions. |
default | ErrorEnvelope | Error 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 /pattern-labels
Declare a pattern label
Creates a binary derived label whose outcome is a behavioral pattern over each anchor's future window (t, t + horizon_days] (WP-C7 req 4): sum(transfer.outbound.amount) over 30 days \>= 1000, an ordering such as a losing bet followed by a deposit within 48 hours, or a rise relative to trailing baselines. The pattern is validated by THE pattern grammar validator; every trailing window must fit inside the horizon, and the recurrence template is not available (use a count window_agg or a sequence min_count under custom). outcome defaults from template (churn → absence, conversion → presence; custom requires it). maturation_days is bound to horizon_days. Anchors, censoring, emission and leakage registration are exactly those of POST /labels derived labels (WP-C6). Archive with DELETE /labels/\{label_id\}; stats and provenance are read with the /labels/\{label_id\} routes.
Operation ID: createPatternLabel · Service: gateway-api
Authentication
apiKey(http (bearer)) — Project API key (003 §2):tsk_live_…ortsk_test_…inAuthorization: Bearer. Scoped to exactly one project + environment; scopes are a subset ofingest,read,admin. Keys are stored hashed and shown once at creation.consoleSession(http (bearer)) — Console session (003 §2): Identity Platform JWT. Data-plane calls addX-Tessera-Project+X-Tessera-Environmentheaders, validated against org membership.
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
Idempotency-Key | header | no | string | Idempotency 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
Responses
| Status | Schema | Description |
|---|---|---|
201 | PatternLabelDefinition | The created pattern label definition. |
default | ErrorEnvelope | Error 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 /pattern-labels/{label_id}
Get one pattern label definition
The stored pattern label. Another tenant's label id, and a label that is not a pattern label, are indistinguishable from a missing one (404 not_found, 003 §3).
Operation ID: getPatternLabel · Service: gateway-api
Authentication
apiKey(http (bearer)) — Project API key (003 §2):tsk_live_…ortsk_test_…inAuthorization: Bearer. Scoped to exactly one project + environment; scopes are a subset ofingest,read,admin. Keys are stored hashed and shown once at creation.consoleSession(http (bearer)) — Console session (003 §2): Identity Platform JWT. Data-plane calls addX-Tessera-Project+X-Tessera-Environmentheaders, validated against org membership.
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
label_id | path | yes | string | Label id (lbl_ ULID, 002 §1). |
Responses
| Status | Schema | Description |
|---|---|---|
200 | PatternLabelDefinition | The pattern label definition. |
default | ErrorEnvelope | Error 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 /pattern-labels/{label_id}
Update a pattern label definition
Updates description and backdating_limit_days, and replaces the whole rule until the label's first successful materialization is recorded (WP-C6 req 5) — afterwards the rule is immutable (400 failed_precondition, reason derived_rule_frozen: a changed rule is a different outcome; create a new label). A replaced rule re-binds maturation_days to its horizon_days. Unknown members fail with 400 invalid_argument.
Operation ID: updatePatternLabel · Service: gateway-api
Authentication
apiKey(http (bearer)) — Project API key (003 §2):tsk_live_…ortsk_test_…inAuthorization: Bearer. Scoped to exactly one project + environment; scopes are a subset ofingest,read,admin. Keys are stored hashed and shown once at creation.consoleSession(http (bearer)) — Console session (003 §2): Identity Platform JWT. Data-plane calls addX-Tessera-Project+X-Tessera-Environmentheaders, validated against org membership.
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
label_id | path | yes | string | Label id (lbl_ ULID, 002 §1). |
Request body
Responses
| Status | Schema | Description |
|---|---|---|
200 | PatternLabelDefinition | The updated pattern label definition. |
default | ErrorEnvelope | Error 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 /pattern-labels/{label_id}:restore
Restore an archived pattern label
Un-archives a pattern label (WP-O4; the POST /labels/\{label_id\}:restore twin for pattern labels): status=active, archived_at cleared. Restoring an already-active label is a no-op success (200).
Operation ID: restorePatternLabel · Service: gateway-api
Authentication
apiKey(http (bearer)) — Project API key (003 §2):tsk_live_…ortsk_test_…inAuthorization: Bearer. Scoped to exactly one project + environment; scopes are a subset ofingest,read,admin. Keys are stored hashed and shown once at creation.consoleSession(http (bearer)) — Console session (003 §2): Identity Platform JWT. Data-plane calls addX-Tessera-Project+X-Tessera-Environmentheaders, validated against org membership.
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
Idempotency-Key | header | no | string | Idempotency 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. |
label_id | path | yes | string | Label id (lbl_ 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.
Responses
| Status | Schema | Description |
|---|---|---|
200 | PatternLabelDefinition | The restored (or already active) pattern label definition. |
default | ErrorEnvelope | Error 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 /pattern-labels:preview
Dry-run an unsaved pattern label rule
The POST /labels:preview dry run for an UNSAVED pattern rule (WP-C6 R18, WP-C7 req 4): validated exactly like POST /pattern-labels, evaluated by THE materializer over up to sample_entities sampled entities of the type with snapshot_time = now, over the same window (the newest days of the type's events), entity sample (spread over the entities seen on the window's days up to the censor clock − horizon_days), deadline, process limits and warnings as POST /labels:preview, with the same censor clock min(now, the newest event of that type in the store) (WP-M26); nothing is persisted. An entity whose erasure has begun is left out and not replaced, so sampled_entities can be smaller than sample_entities, and its events never set the censor clock (with the same retryable 503 as POST /labels:preview). Entity ids only appear as entity_hash (002 §3).
Operation ID: previewPatternLabel · Service: gateway-api
Authentication
apiKey(http (bearer)) — Project API key (003 §2):tsk_live_…ortsk_test_…inAuthorization: Bearer. Scoped to exactly one project + environment; scopes are a subset ofingest,read,admin. Keys are stored hashed and shown once at creation.consoleSession(http (bearer)) — Console session (003 §2): Identity Platform JWT. Data-plane calls addX-Tessera-Project+X-Tessera-Environmentheaders, validated against org membership.
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
Idempotency-Key | header | no | string | Idempotency 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
Responses
| Status | Schema | Description |
|---|---|---|
200 | LabelPreviewResponse | The dry-run evaluation over the sampled entities. |
default | ErrorEnvelope | Error 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.