Skip to main content

sso

POST /auth/sso:discover​

Discover SSO for an email address

Unauthenticated SP-initiated discovery (003 §4, WP-A4 req 9): the console calls this before sign-in, then runs Identity Platform's signInWithRedirect against the returned tenant. Returns \{sso: true, tenant_id, provider_kind\} only when the email's domain is verified and its org's SSO is configured or enforced; every other input gets the constant shape \{sso: false\} — org names and tenant ids are never disclosed for unverified or disabled configs. Rate-limited per client IP (429 resource_exhausted with retry_after_seconds).

Operation ID: discoverSso · Service: gateway-api

Authentication​

None — this operation is public.

Request body​

SsoDiscoverRequest

Responses​

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

GET /orgs/{org_id}/sso​

Get the organization's SSO configuration

The org's SSO configuration (WP-A4). Requires role admin or above. The OIDC client_secret is write-only and is never present in the response (WP-A4 req 2); the response includes the verified-domain summary and status. 404 not_found until the first PUT.

Operation ID: getOrgSso · Service: gateway-api

Authentication​

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

Parameters​

NameInRequiredTypeDescription
org_idpathyesstringOrganization id (org_ ULID).

Responses​

StatusSchemaDescription
200SsoConfigThe organization's SSO configuration.
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.

PUT /orgs/{org_id}/sso​

Configure the organization's SSO provider

Creates or replaces the org's SSO configuration (WP-A4 req 1). Requires role admin or above and a verified email. The first configuration provisions the org's Identity Platform tenant; the request attaches/replaces exactly one SAML or OIDC inbound provider on it. Invalid provider material (unparsable certificate, non-HTTPS sso_url/issuer) fails 400 invalid_argument before any Identity Platform call. status="enforced" requires at least one verified domain and a recorded SSO sign-in (last_sso_login_at non-null), else 400 failed_precondition (WP-A4 req 7). status="disabled" keeps users and memberships intact (WP-A4 req 10).

Operation ID: putOrgSso · Service: gateway-api

Authentication​

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

Parameters​

NameInRequiredTypeDescription
org_idpathyesstringOrganization id (org_ ULID).

Request body​

SsoConfigUpdate

Responses​

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

GET /orgs/{org_id}/sso/default-role​

Read the SSO just-in-time role, including a custom role.

The closed v1 SsoConfig reports a custom default as viewer. This read returns the exact reference. 404 not_found until SSO is configured with PUT /orgs/\{org_id\}/sso.

Operation ID: getOrgSsoDefaultRole · Service: gateway-api

Authentication​

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

Parameters​

NameInRequiredTypeDescription
org_idpathyesstring

Responses​

StatusSchemaDescription
200SsoDefaultRoleSettingThe exact default role reference.
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.

PUT /orgs/{org_id}/sso/default-role​

Set the SSO just-in-time role to a built-in or custom role.

Changes only default_role of an existing SSO configuration; no Identity Platform call is made. owner is never granted by JIT provisioning. A custom role must belong to this organization and its permissions must be a subset of the actor's effective org permissions. PUT /orgs/\{org_id\}/sso replaces the whole configuration, including this default, with its closed built-in value (member when omitted).

Operation ID: putOrgSsoDefaultRole · Service: gateway-api

Authentication​

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

Parameters​

NameInRequiredTypeDescription
org_idpathyesstring

Request body​

SsoDefaultRoleSetting

Responses​

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

GET /orgs/{org_id}/sso/domains​

List captured domains

Cursor-paginated list of the org's captured email domains (003 §1). Requires role admin or above.

Operation ID: listSsoDomains · Service: gateway-api

Authentication​

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

Parameters​

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

Pagination​

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

Responses​

StatusSchemaDescription
200SsoDomainPagePage of captured domains.
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 /orgs/{org_id}/sso/domains​

Capture an email domain

Stores the domain in state pending with a random 32-byte verification token (WP-A4 req 3); verification requires the DNS TXT record tessera-verification=\<token\> on _tessera.\<domain\>. The token is not a secret capability (it only proves domain control when published) and is re-displayed on reads. Public-suffix and shared consumer email domains (e.g. co.uk, gmail.com) are rejected 400 invalid_argument against the vendored public-suffix list (WP-A4 req 4). A domain already verified by a different org fails 409 already_exists — one org owns a domain. Requires role admin or above and a verified email.

Operation ID: addSsoDomain · Service: gateway-api

Authentication​

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

Parameters​

NameInRequiredTypeDescription
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.
org_idpathyesstringOrganization id (org_ ULID).

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​

SsoDomainCreateRequest

Responses​

StatusSchemaDescription
201SsoDomainThe captured domain, pending verification.
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.

DELETE /orgs/{org_id}/sso/domains/{domain}​

Remove a captured domain

Removes the domain from the org's capture list. Requires role admin or above and a verified email. Removing a verified domain immediately stops discovery and enforced-SSO matching for it; users and memberships are untouched.

Operation ID: removeSsoDomain · Service: gateway-api

Authentication​

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

Parameters​

NameInRequiredTypeDescription
domainpathyesstringThe captured domain (lowercase).
org_idpathyesstringOrganization id (org_ ULID).

Responses​

StatusSchemaDescription
204—Domain removed.
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 /orgs/{org_id}/sso/domains/{domain}:verify​

Verify a captured domain via DNS TXT

Re-resolves _tessera.\<domain\> TXT live and flips the domain to verified when a record equals tessera-verification=\<token\> (003 §1 custom action; WP-A4 req 3). Mismatch or NXDOMAIN fails 400 failed_precondition with the observed TXT strings in error.details; a domain meanwhile verified by a different org fails 409 already_exists. Requires role admin or above and a verified email. Idempotent: an already-verified domain returns 200 without re-resolving.

Operation ID: verifySsoDomain · Service: gateway-api

Authentication​

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

Parameters​

NameInRequiredTypeDescription
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.
domainpathyesstringThe captured domain (lowercase).
org_idpathyesstringOrganization id (org_ ULID).

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​

StatusSchemaDescription
200SsoDomainThe domain, now verified.
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.