API reference · API 1.0.0

Tenants

Tenants of a customer and their memberships.

get /api/v1/tenants

List tenants

Operation tenants_list · bearer token

The tenants of this platform, in slug order. The filters are exact and combine: customer_id (that customer's tenants), slug.

Parameters

NameInTypeDescription
customer_id query string | null

Only this customer's tenants.

pattern ^[1-9][0-9]{0,8}$
slug query string | null

Exact slug.

limit query integer

Page size.

min 1 · max 200 · default 50
cursor query string | null

next_cursor from the previous page; omit it for the first page. A cursor this list did not issue is a 400 invalid_cursor.

Responses

  • 200

    One page of tenants.

    application/json → TenantPage
    Headers: X-Request-ID
  • 401

    Not authenticated: no Authorization: Bearer header (not_authenticated), or the credential is refused (token_invalid, token_expired, token_revoked, principal_disabled, token_ip_not_allowed).

    application/jsonapplication/problem+json → Problem
  • 403

    The caller lacks a permission the operation needs (forbidden; required lists the keys, any one of which would do), or the licence refuses a change (licence_locked, licence_restricted, licence_required, with state and remedy; never retry a licence_* code).

    application/jsonapplication/problem+json → Problem
    Headers: X-Request-ID
  • 429

    More than 600 requests in a minute with this token (rate_limited), or the first request with this Idempotency-Key is still running (idempotency_request_in_progress). Retry after Retry-After.

    application/jsonapplication/problem+json → Problem
  • 503

    The platform cannot answer right now (unavailable; retry after Retry-After), or API tokens are not configured on it (api_tokens_unconfigured; an operator must act).

    application/jsonapplication/problem+json → Problem
  • default

    Problem details (RFC 9457)

    application/jsonapplication/problem+json → Problem
    Headers: X-Request-ID
post /api/v1/tenants

Register a tenant

Operation tenants_create · bearer token

Registers a further tenant of an existing customer (a customer's primary tenant is made with the customer). A person signed in to the portal becomes the tenant's owner; a token's owner does not, so a tenant created with a token starts with no members (PUT /tenants/{id}/memberships/{user_id} adds them). customer_id and slug are frozen once created. Send an Idempotency-Key to make a retry safe: a retry with the same key and request gets the first answer and changes nothing.

Parameters

NameInTypeDescription
Idempotency-Key header string

Makes a retry safe: for 24 hours, the same key with the same request (method, path, query and body) answers with the stored response (Idempotent-Replayed: true) instead of doing the work again. The same key with a different request is a 409 idempotency_key_reused; while the first request is still running it is a 429 idempotency_request_in_progress with Retry-After. 1-255 printable characters without spaces (400 invalid_idempotency_key otherwise); a UUID is a good key. Keys are scoped to the calling account.

min length 1 · max length 255 · pattern ^[!-~]+$

Request bodyrequired

application/json

Schema TenantCreate

A further tenant of an existing customer.

NameTypeDescription
customer_idrequired string

The customer the tenant belongs to. Frozen after create.

pattern ^[1-9][0-9]{0,8}$
default_router_id string | null

The id of the tenant's default router; null when none is set.

pattern ^[1-9][0-9]{0,8}$
description string | null

Free text, up to 2000 characters.

max length 2000
namerequired string

The tenant's display name.

min length 2 · max length 120
slugrequired string

Lowercase letters, digits and '-', starting with a letter, 2-30 characters. Frozen after create.

pattern ^[a-z][a-z0-9-]{1,29}$

Responses

  • 201

    The tenant was registered.

    application/json → Tenant
  • 401

    Not authenticated: no Authorization: Bearer header (not_authenticated), or the credential is refused (token_invalid, token_expired, token_revoked, principal_disabled, token_ip_not_allowed).

    application/jsonapplication/problem+json → Problem
  • 403

    The caller lacks a permission the operation needs (forbidden; required lists the keys, any one of which would do), or the licence refuses a change (licence_locked, licence_restricted, licence_required, with state and remedy; never retry a licence_* code).

    application/jsonapplication/problem+json → Problem
    Headers: X-Request-ID
  • 409

    The slug is taken (tenant_slug_taken) or the customer is archived (customer_archived).

    application/jsonapplication/problem+json → Problem
    Headers: X-Request-ID
  • 422

    No such customer (customer_not_found) or router (default_router_not_found), or the body is invalid.

    application/jsonapplication/problem+json → Problem
    Headers: X-Request-ID
  • 429

    More than 600 requests in a minute with this token (rate_limited), or the first request with this Idempotency-Key is still running (idempotency_request_in_progress). Retry after Retry-After.

    application/jsonapplication/problem+json → Problem
  • 503

    The platform cannot answer right now (unavailable; retry after Retry-After), or API tokens are not configured on it (api_tokens_unconfigured; an operator must act).

    application/jsonapplication/problem+json → Problem
  • default

    Problem details (RFC 9457)

    application/jsonapplication/problem+json → Problem
    Headers: X-Request-ID
get /api/v1/tenants/{tenant_id}

One tenant

Operation tenants_get · bearer token

One tenant by id, with its project and member counts.

Parameters

NameInTypeDescription
tenant_idrequired path string

Responses

  • 200

    The tenant.

    application/json → Tenant
    Headers: X-Request-ID
  • 401

    Not authenticated: no Authorization: Bearer header (not_authenticated), or the credential is refused (token_invalid, token_expired, token_revoked, principal_disabled, token_ip_not_allowed).

    application/jsonapplication/problem+json → Problem
  • 403

    The caller lacks a permission the operation needs (forbidden; required lists the keys, any one of which would do), or the licence refuses a change (licence_locked, licence_restricted, licence_required, with state and remedy; never retry a licence_* code).

    application/jsonapplication/problem+json → Problem
    Headers: X-Request-ID
  • 404

    No such tenant (tenant_not_found).

    application/jsonapplication/problem+json → Problem
    Headers: X-Request-ID
  • 429

    More than 600 requests in a minute with this token (rate_limited), or the first request with this Idempotency-Key is still running (idempotency_request_in_progress). Retry after Retry-After.

    application/jsonapplication/problem+json → Problem
  • 503

    The platform cannot answer right now (unavailable; retry after Retry-After), or API tokens are not configured on it (api_tokens_unconfigured; an operator must act).

    application/jsonapplication/problem+json → Problem
  • default

    Problem details (RFC 9457)

    application/jsonapplication/problem+json → Problem
    Headers: X-Request-ID
patch /api/v1/tenants/{tenant_id}

Change a tenant

Operation tenants_update · bearer token

Only the members in the body change. customer_id and slug are frozen: sending the current value is accepted, a different one is a 422.

The body is a JSON Merge Patch (RFC 7396), sent as application/merge-patch+json or application/json: a member that is omitted is left unchanged, and a member set to null clears that field where clearing is allowed (the schema marks those fields nullable; null for any other field is a 422).

Parameters

NameInTypeDescription
tenant_idrequired path string

Request bodyrequired

application/jsonapplication/merge-patch+json

Schema TenantPatch

JSON Merge Patch (RFC 7396): a member that is omitted keeps its current value; a member sent as null clears the field when the field is nullable (the schema marks it so), and null for any other field is a 422. A "" is a value (an empty string), not a clear. description and default_router_id are nullable; name is not.

NameTypeDescription
customer_id string | null

Frozen.

default_router_id string | null

null clears it.

pattern ^[1-9][0-9]{0,8}$
description string | null

Free text, up to 2000 characters. null clears it.

max length 2000
name string | null

The tenant's display name.

min length 2 · max length 120
slug string | null

Frozen.

Responses

  • 200

    The tenant after the change.

    application/json → Tenant
    Headers: X-Request-ID
  • 401

    Not authenticated: no Authorization: Bearer header (not_authenticated), or the credential is refused (token_invalid, token_expired, token_revoked, principal_disabled, token_ip_not_allowed).

    application/jsonapplication/problem+json → Problem
  • 403

    The caller lacks a permission the operation needs (forbidden; required lists the keys, any one of which would do), or the licence refuses a change (licence_locked, licence_restricted, licence_required, with state and remedy; never retry a licence_* code).

    application/jsonapplication/problem+json → Problem
    Headers: X-Request-ID
  • 404

    No such tenant (tenant_not_found).

    application/jsonapplication/problem+json → Problem
    Headers: X-Request-ID
  • 422

    A frozen key was changed (immutable_field), no such router (default_router_not_found), or the body is invalid.

    application/jsonapplication/problem+json → Problem
    Headers: X-Request-ID
  • 429

    More than 600 requests in a minute with this token (rate_limited), or the first request with this Idempotency-Key is still running (idempotency_request_in_progress). Retry after Retry-After.

    application/jsonapplication/problem+json → Problem
  • 503

    The platform cannot answer right now (unavailable; retry after Retry-After), or API tokens are not configured on it (api_tokens_unconfigured; an operator must act).

    application/jsonapplication/problem+json → Problem
  • default

    Problem details (RFC 9457)

    application/jsonapplication/problem+json → Problem
    Headers: X-Request-ID
delete /api/v1/tenants/{tenant_id}

Delete an empty tenant

Operation tenants_delete · bearer token

Deletes the tenant only when nothing but memberships hangs off it: no project of any status, no contract, no helpdesk record, no attributed resource, no live AI gateway key (a deleted key's registry row is kept and detached). Its memberships go with it, and its SSO /tenants/<slug> groups are removed. Service grants are NOT revoked: a user's grants are held per customer, not per tenant, and stay in force until revoked in the portal.

Parameters

NameInTypeDescription
tenant_idrequired path string

Responses

  • 204

    The tenant was deleted.

    Headers: X-Request-ID
  • 401

    Not authenticated: no Authorization: Bearer header (not_authenticated), or the credential is refused (token_invalid, token_expired, token_revoked, principal_disabled, token_ip_not_allowed).

    application/jsonapplication/problem+json → Problem
  • 403

    A token created without allow_destroy (destroy_not_allowed). Also: the caller lacks a permission the operation needs (forbidden; required lists the keys, any one of which would do), or the licence refuses a change (licence_locked, licence_restricted, licence_required, with state and remedy; never retry a licence_* code).

    application/jsonapplication/problem+json → Problem
    Headers: X-Request-ID
  • 404

    No such tenant (tenant_not_found).

    application/jsonapplication/problem+json → Problem
    Headers: X-Request-ID
  • 409

    The tenant is a customer's primary tenant (tenant_is_primary) or is not empty: tenant_has_projects, tenant_has_contracts, tenant_has_helpdesk_records, tenant_has_attributed_resources, tenant_has_ai_gateway_keys (live AI gateway keys). blockers counts each. tenant_in_use: something else still refers to the tenant (no blockers).

    application/jsonapplication/problem+json → Problem
    Headers: X-Request-ID
  • 429

    More than 600 requests in a minute with this token (rate_limited), or the first request with this Idempotency-Key is still running (idempotency_request_in_progress). Retry after Retry-After.

    application/jsonapplication/problem+json → Problem
  • 503

    The platform cannot answer right now (unavailable; retry after Retry-After), or API tokens are not configured on it (api_tokens_unconfigured; an operator must act).

    application/jsonapplication/problem+json → Problem
  • default

    Problem details (RFC 9457)

    application/jsonapplication/problem+json → Problem
    Headers: X-Request-ID
get /api/v1/tenants/{tenant_id}/memberships

A tenant's memberships

Operation tenant_memberships_list · bearer token

The tenant's members and their roles, in user_id order.

Parameters

NameInTypeDescription
tenant_idrequired path string
limit query integer

Page size.

min 1 · max 200 · default 50
cursor query string | null

next_cursor from the previous page; omit it for the first page. A cursor this list did not issue is a 400 invalid_cursor.

Responses

  • 200

    One page of the tenant's memberships.

    application/json → MembershipPage
    Headers: X-Request-ID
  • 401

    Not authenticated: no Authorization: Bearer header (not_authenticated), or the credential is refused (token_invalid, token_expired, token_revoked, principal_disabled, token_ip_not_allowed).

    application/jsonapplication/problem+json → Problem
  • 403

    The caller lacks a permission the operation needs (forbidden; required lists the keys, any one of which would do), or the licence refuses a change (licence_locked, licence_restricted, licence_required, with state and remedy; never retry a licence_* code).

    application/jsonapplication/problem+json → Problem
    Headers: X-Request-ID
  • 404

    No such tenant (tenant_not_found).

    application/jsonapplication/problem+json → Problem
    Headers: X-Request-ID
  • 429

    More than 600 requests in a minute with this token (rate_limited), or the first request with this Idempotency-Key is still running (idempotency_request_in_progress). Retry after Retry-After.

    application/jsonapplication/problem+json → Problem
  • 503

    The platform cannot answer right now (unavailable; retry after Retry-After), or API tokens are not configured on it (api_tokens_unconfigured; an operator must act).

    application/jsonapplication/problem+json → Problem
  • default

    Problem details (RFC 9457)

    application/jsonapplication/problem+json → Problem
    Headers: X-Request-ID
get /api/v1/tenants/{tenant_id}/memberships/{user_id}

One membership

Operation tenant_memberships_get · bearer token

One person's membership of the tenant. 404 membership_not_found when they are not a member.

Parameters

NameInTypeDescription
tenant_idrequired path string
user_idrequired path string

Responses

  • 200

    The membership.

    application/json → Membership
    Headers: X-Request-ID
  • 401

    Not authenticated: no Authorization: Bearer header (not_authenticated), or the credential is refused (token_invalid, token_expired, token_revoked, principal_disabled, token_ip_not_allowed).

    application/jsonapplication/problem+json → Problem
  • 403

    The caller lacks a permission the operation needs (forbidden; required lists the keys, any one of which would do), or the licence refuses a change (licence_locked, licence_restricted, licence_required, with state and remedy; never retry a licence_* code).

    application/jsonapplication/problem+json → Problem
    Headers: X-Request-ID
  • 404

    No such tenant (tenant_not_found) or membership (membership_not_found).

    application/jsonapplication/problem+json → Problem
    Headers: X-Request-ID
  • 429

    More than 600 requests in a minute with this token (rate_limited), or the first request with this Idempotency-Key is still running (idempotency_request_in_progress). Retry after Retry-After.

    application/jsonapplication/problem+json → Problem
  • 503

    The platform cannot answer right now (unavailable; retry after Retry-After), or API tokens are not configured on it (api_tokens_unconfigured; an operator must act).

    application/jsonapplication/problem+json → Problem
  • default

    Problem details (RFC 9457)

    application/jsonapplication/problem+json → Problem
    Headers: X-Request-ID
put /api/v1/tenants/{tenant_id}/memberships/{user_id}

Add a member or change their role

Operation tenant_memberships_put · bearer token

201 when the membership was created, 200 when an existing one was set.

Parameters

NameInTypeDescription
tenant_idrequired path string
user_idrequired path string

Request bodyrequired

application/json

Schema MembershipPut

The member's role in the tenant.

NameTypeDescription
rolerequired string

owner, admin, member or viewer.

one of owner, admin, member, viewer

Responses

  • 200

    The existing membership's role was set.

    application/json → Membership
    Headers: X-Request-ID
  • 201

    The membership was created.

    application/json → Membership
    Headers: X-Request-ID
  • 401

    Not authenticated: no Authorization: Bearer header (not_authenticated), or the credential is refused (token_invalid, token_expired, token_revoked, principal_disabled, token_ip_not_allowed).

    application/jsonapplication/problem+json → Problem
  • 403

    The caller lacks a permission the operation needs (forbidden; required lists the keys, any one of which would do), or the licence refuses a change (licence_locked, licence_restricted, licence_required, with state and remedy; never retry a licence_* code).

    application/jsonapplication/problem+json → Problem
    Headers: X-Request-ID
  • 404

    No such tenant (tenant_not_found) or user (user_not_found).

    application/jsonapplication/problem+json → Problem
    Headers: X-Request-ID
  • 429

    More than 600 requests in a minute with this token (rate_limited), or the first request with this Idempotency-Key is still running (idempotency_request_in_progress). Retry after Retry-After.

    application/jsonapplication/problem+json → Problem
  • 503

    The platform cannot answer right now (unavailable; retry after Retry-After), or API tokens are not configured on it (api_tokens_unconfigured; an operator must act).

    application/jsonapplication/problem+json → Problem
  • default

    Problem details (RFC 9457)

    application/jsonapplication/problem+json → Problem
    Headers: X-Request-ID
delete /api/v1/tenants/{tenant_id}/memberships/{user_id}

Remove a member

Operation tenant_memberships_delete · bearer token

Removes the user's membership of the tenant and re-syncs their SSO groups. This is NOT destroy-gated: it needs the write permission only, not a token created with allow_destroy. Service grants are NOT revoked: a user's grants are held per customer, not per tenant, and stay in force until revoked in the portal.

Parameters

NameInTypeDescription
tenant_idrequired path string
user_idrequired path string

Responses

  • 204

    The membership was removed.

    Headers: X-Request-ID
  • 401

    Not authenticated: no Authorization: Bearer header (not_authenticated), or the credential is refused (token_invalid, token_expired, token_revoked, principal_disabled, token_ip_not_allowed).

    application/jsonapplication/problem+json → Problem
  • 403

    The caller lacks a permission the operation needs (forbidden; required lists the keys, any one of which would do), or the licence refuses a change (licence_locked, licence_restricted, licence_required, with state and remedy; never retry a licence_* code).

    application/jsonapplication/problem+json → Problem
    Headers: X-Request-ID
  • 404

    No such tenant (tenant_not_found) or membership (membership_not_found).

    application/jsonapplication/problem+json → Problem
    Headers: X-Request-ID
  • 429

    More than 600 requests in a minute with this token (rate_limited), or the first request with this Idempotency-Key is still running (idempotency_request_in_progress). Retry after Retry-After.

    application/jsonapplication/problem+json → Problem
  • 503

    The platform cannot answer right now (unavailable; retry after Retry-After), or API tokens are not configured on it (api_tokens_unconfigured; an operator must act).

    application/jsonapplication/problem+json → Problem
  • default

    Problem details (RFC 9457)

    application/jsonapplication/problem+json → Problem
    Headers: X-Request-ID

Rendered from openapi-v1.json, platform release 1.0.187. Your installation serves the contract of its own version at /api/v1/openapi.json.