Skip to main content
DocumentationIdentity and access · console.eu.ccsio.ai

Members

An organization's members and invitations: add, change, remove, invite, block and unblock, transfer to another organization, and help a member sign in.

Documentation menu

The descriptions of the operations and fields are the contract’s own, in English.

GET/identity/v1/organizations/{org}/members

List organization-level members

Credential
API key
Permission
Any ofmembers.readsupport-access.read

Lists the organization-level role bindings (the members of the organization itself; the members of a team are listed per team), deterministic by user_ref. status selects active (the default), disabled (blocked) or removed. Nothing in the status asked for is an empty list, never a 404.

curl
curl "https://console.eu.ccsio.ai/identity/v1/organizations/{org}/members" \
  -H "Authorization: Bearer $CCSIO_API_KEY"

Parameters

NameInDescription
X-Request-ID
optional
headerstring

Optional request ULID. A valid ULID (upper or lowercase) is honored; when the header is absent or invalid, the runtime mints the id. The response X-Request-ID header carries the canonical uppercase form.

org
required
pathstring

The organization id (C7 identifier). A value outside the pattern is refused with 400 name-invalid.

status
optional
querystring

The membership status filter: active (default), disabled or removed. Any other value is refused with 400 invalid-request.

Responses

  • 200

    The organization-level roster.

    Schema
    ListRoleBindingsResponse
    • membersarray of RoleBindingrequired
      • emailstringoptional

        Provider profile email when known; never an authorization identifier.

      • display_namestringoptional

        Readable human or service account name when known.

      • kindstringoptional

        Allowed values: "human""service_account"

      • organization_idstringrequired

        pattern ^[a-z][a-z0-9._-]{0,63}$

      • team_idstring or nullrequired

        null for an organization-level binding.

        pattern ^[a-z][a-z0-9._-]{0,63}$

      • user_refstringrequired

        pattern ^[A-Za-z0-9][A-Za-z0-9._:/-]{0,127}$

      • rolestringrequired

        The binding's role: a built-in role id or the id of one of the organization's custom roles.

        pattern ^(ccsio_admin|root|organization_admin|team_admin|user|role_[a-z0-9_]{1,59})$

      • statusstringrequired

        Allowed values: "active""disabled""removed"

      • created_atstring (date-time)required

        RFC 3339, second precision, UTC.

      • updated_atstring (date-time)required

        RFC 3339, second precision, UTC.

  • 400

    Client refusal unrelated to authentication, including malformed input, a denied or failed request.

  • 401

    The request carries no credential, more than one, or one the platform does not accept, and is refused before the operation runs; `error.code` says why. Supply exactly one credential. Codes: invalid-request (no credential, or both Authorization:

    Read more

    Bearer and x-api-key), api-key-invalid (a value that is not a platform API key, or a key of a kind the platform does not accept), api-key-unknown, api-key-revoked, api-key-expired, bootstrap-disabled (the one-shot installation credential, once a key exists), token-malformed (a bearer token that is not a JWT), token-algorithm-unsupported, token-signature-invalid, token-claim-invalid, token-issuer-mismatch, token-audience-mismatch, token-expired, token-not-yet-valid, issuer-untrusted, issuer-residency-mismatch (the issuer belongs to another plane), issuer-resolution-unknown, jwks-unavailable, jwks-key-not-found, staff-token-inactive (a platform operator's token), staff-not-operator, staff-directory-unavailable, identity-not-provisioned (a verified identity with no account on this plane), organization-not-found (a verified identity or key whose organization this plane does not know), internal-error (a fault while the credential is checked is refused too, fail closed), context-cancelled

  • 402

    The organization has to pay first: its standing is payment_required.

    Read more

    The request boundary applies this payment gate to every route except an organization's billing routes, the caller's own context, organization list, onboarding, session report and personal keys, the public routes, and the routes of platform operators, who administer an organization that has to pay. The operations the gate covers declare this response. On /v1 the refusal is rendered in the OpenAI error format. Code: payment-required

  • 403

    The credential is valid but may not do this here; the request is refused by the request boundary before the handler runs, and `error.code` says which refusal. An operation may add codes of its own.

    Read more

    Codes: policy-denied (no role of the caller holds the permission the operation needs, or the credential class may not call it: a personal API key outside inference and MCP, a route that needs a signed-in person, the one-shot installation credential outside its three steps), tenant-mismatch (the organization a path, query, body or X-Tenant header names is not the caller's own), organization-provisioning, organization-suspended, organization-disabled, organization-deleted (the state of the caller's organization), user-disabled, residency-mismatch (the organization lives on another plane), organization-selection-required (a caller with more than one organization, or a platform operator, must name one in X-Organization-Id), organization-not-selectable, no-active-organization-membership, team-not-selectable (the X-Organization-Id or X-Team-Id the caller sent does not name an organization or team it may act in), identity-managed-by-provider (a person who is not a platform operator changes an organization's status, which belongs to the identity provider), support-session-required (a platform operator reads an organization's data without an open support session)

  • 404

    The requested resource or path was not found.

  • 405

    The path is claimed but the request method is not allowed. Go ServeMux returns its standard plain-text response and lists permitted methods in Allow.

  • 500

    Platform failure, rendered without internal cause details.

  • 503

    A dependency the operation needs is not configured on this plane or could not be reached, and nothing was changed. `error.code` names it; an operation lists the ones it can answer besides the boundary's. Retry later. Codes: support-audit-unavailable (the request boundary: an operator's read under an open support session could not be recorded, so nothing was served)

POST/identity/v1/organizations/{org}/members

Add (or re-activate) an organization-level member

Credential
API key
Permission
members.manage
Request body
Body up to 1 MiB

user_ref and role are required; confirm_extra_seat is optional (default false). role accepts any organization-level role: the built-in root, organization_admin and user, or the id of one of the organization's custom roles (GET .../roles lists them; an id the organization does not have is 400 role-invalid).

Read more

Upsert: an active duplicate is a no-op (the stored role is never rewritten); a removed or disabled row is re-activated keeping its stored role. Escalation: the acting principal (the verified caller, never a request field) must be able to manage members (root, organization_admin, a platform ccsio_admin, or a custom role carrying members.manage) and able to grant the role being written, and, on a re-add, the role the row already holds: a built-in administrator outranks or equals a built-in role; every role, built-in or custom, must have permissions the actor effectively holds at this scope; a custom-role holder can never grant root, organization_admin or team_admin. Seats: when billing is on, adding or re-activating a human who has no access yet needs a seat; if the organization has none left, the request is refused with 409 seat-confirmation-required when the plan lets it buy one more (repeat with confirm_extra_seat true once the administrator confirms the extra charge) or 409 seat-limit-reached when it cannot; a service account that would exceed the organization's limit is 409 service-account-limit-reached.

curl
curl -X POST "https://console.eu.ccsio.ai/identity/v1/organizations/{org}/members" \
  -H "Authorization: Bearer $CCSIO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "user_ref": "user/onboard/01K7YN2C4D6F8H1K3M5P7R9T0V",
  "role": "organization_admin"
}'

Parameters

NameInDescription
X-Request-ID
optional
headerstring

Optional request ULID. A valid ULID (upper or lowercase) is honored; when the header is absent or invalid, the runtime mints the id. The response X-Request-ID header carries the canonical uppercase form.

org
required
pathstring

The organization id (C7 identifier). A value outside the pattern is refused with 400 name-invalid.

Request body application/json

AddRoleBindingRequest
  • user_refstringrequired

    pattern ^[A-Za-z0-9][A-Za-z0-9._:/-]{0,127}$

  • rolestringrequired

    The same role as RoleBindingRequest: a built-in role id or a custom role id (role_<id>), of which only the organization-level subset (root, organization_admin, user and custom roles) is legal on THIS operation.

    pattern ^(ccsio_admin|root|organization_admin|team_admin|user|role_[a-z0-9_]{1,59})$

  • confirm_extra_seatbooleanoptional

    Optional (default false): confirms the extra charge when adding this member needs one more seat than the plan includes (409 seat-confirmation-required without it). Only an addition can need a seat, so the role change shares RoleBindingRequest without this member.

Responses

  • 200

    The added or re-activated organization-level role binding.

    Schema
    RoleBinding
    • emailstringoptional

      Provider profile email when known; never an authorization identifier.

    • display_namestringoptional

      Readable human or service account name when known.

    • kindstringoptional

      Allowed values: "human""service_account"

    • organization_idstringrequired

      pattern ^[a-z][a-z0-9._-]{0,63}$

    • team_idstring or nullrequired

      null for an organization-level binding.

      pattern ^[a-z][a-z0-9._-]{0,63}$

    • user_refstringrequired

      pattern ^[A-Za-z0-9][A-Za-z0-9._:/-]{0,127}$

    • rolestringrequired

      The binding's role: a built-in role id or the id of one of the organization's custom roles.

      pattern ^(ccsio_admin|root|organization_admin|team_admin|user|role_[a-z0-9_]{1,59})$

    • statusstringrequired

      Allowed values: "active""disabled""removed"

    • created_atstring (date-time)required

      RFC 3339, second precision, UTC.

    • updated_atstring (date-time)required

      RFC 3339, second precision, UTC.

  • 400

    Client refusal unrelated to authentication, including malformed input, a denied or failed request.

  • 401

    The request carries no credential, more than one, or one the platform does not accept, and is refused before the operation runs; `error.code` says why. Supply exactly one credential. Codes: invalid-request (no credential, or both Authorization:

    Read more

    Bearer and x-api-key), api-key-invalid (a value that is not a platform API key, or a key of a kind the platform does not accept), api-key-unknown, api-key-revoked, api-key-expired, bootstrap-disabled (the one-shot installation credential, once a key exists), token-malformed (a bearer token that is not a JWT), token-algorithm-unsupported, token-signature-invalid, token-claim-invalid, token-issuer-mismatch, token-audience-mismatch, token-expired, token-not-yet-valid, issuer-untrusted, issuer-residency-mismatch (the issuer belongs to another plane), issuer-resolution-unknown, jwks-unavailable, jwks-key-not-found, staff-token-inactive (a platform operator's token), staff-not-operator, staff-directory-unavailable, identity-not-provisioned (a verified identity with no account on this plane), organization-not-found (a verified identity or key whose organization this plane does not know), internal-error (a fault while the credential is checked is refused too, fail closed), context-cancelled

  • 402

    The organization has to pay first: its standing is payment_required.

    Read more

    The request boundary applies this payment gate to every route except an organization's billing routes, the caller's own context, organization list, onboarding, session report and personal keys, the public routes, and the routes of platform operators, who administer an organization that has to pay. The operations the gate covers declare this response. On /v1 the refusal is rendered in the OpenAI error format. Code: payment-required

  • 403

    The credential is valid but may not do this here; the request is refused by the request boundary before the handler runs, and `error.code` says which refusal. An operation may add codes of its own.

    Read more

    Codes: policy-denied (no role of the caller holds the permission the operation needs, or the credential class may not call it: a personal API key outside inference and MCP, a route that needs a signed-in person, the one-shot installation credential outside its three steps), tenant-mismatch (the organization a path, query, body or X-Tenant header names is not the caller's own), organization-provisioning, organization-suspended, organization-disabled, organization-deleted (the state of the caller's organization), user-disabled, residency-mismatch (the organization lives on another plane), organization-selection-required (a caller with more than one organization, or a platform operator, must name one in X-Organization-Id), organization-not-selectable, no-active-organization-membership, team-not-selectable (the X-Organization-Id or X-Team-Id the caller sent does not name an organization or team it may act in), identity-managed-by-provider (a person who is not a platform operator changes an organization's status, which belongs to the identity provider), support-session-required (a platform operator reads an organization's data without an open support session)

  • 404

    The requested resource or path was not found.

  • 405

    The path is claimed but the request method is not allowed. Go ServeMux returns its standard plain-text response and lists permitted methods in Allow.

  • 409

    The request conflicts with the current state of the resource or with an invariant it protects (a taken name, a role still in use, an organization that must not be deleted, an archived team, the last active root, a seat or service account limit).

  • 500

    Platform failure, rendered without internal cause details.

Example response
{
  "organization_id": "acme",
  "team_id": null,
  "user_ref": "user/onboard/01K7YN2C4D6F8H1K3M5P7R9T0V",
  "role": "organization_admin",
  "status": "active",
  "created_at": "2026-10-14T09:40:00Z",
  "updated_at": "2026-10-14T09:40:00Z",
  "email": "[email protected]",
  "display_name": "Ben Okafor",
  "kind": "human"
}
PATCH/identity/v1/organizations/{org}/members

Change an organization-level member's role

Credential
API key
Permission
members.manage
Request body
Body up to 1 MiB

Same body shape and escalation rule as the add, without confirm_extra_seat (changing a role never needs a seat); operates on an existing binding (404 membership-not-found if absent). Demoting the last active root is 409 root-required.

curl
curl -X PATCH "https://console.eu.ccsio.ai/identity/v1/organizations/{org}/members" \
  -H "Authorization: Bearer $CCSIO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "user_ref": "string",
  "role": "string"
}'
Built from the schema’s required members: replace the values.

Parameters

NameInDescription
X-Request-ID
optional
headerstring

Optional request ULID. A valid ULID (upper or lowercase) is honored; when the header is absent or invalid, the runtime mints the id. The response X-Request-ID header carries the canonical uppercase form.

org
required
pathstring

The organization id (C7 identifier). A value outside the pattern is refused with 400 name-invalid.

Request body application/json

RoleBindingRequest
  • user_refstringrequired

    pattern ^[A-Za-z0-9][A-Za-z0-9._:/-]{0,127}$

  • rolestringrequired

    A built-in role id (ccsio_admin, root, organization_admin, team_admin, user) or a custom role id (role_<id>); the role is a plain string everywhere a role travels. Only the organization-level subset (root, organization_admin, user and custom roles) is ever legal on THIS operation: team_admin (a role legal at team level only) is refused with 400 role-binding-invalid once the acting principal is authorized to act at all; ccsio_admin is refused with 403 membership-forbidden (no organization-level acting principal can ever outrank it); a custom role id the organization does not have is 400 role-invalid.

    pattern ^(ccsio_admin|root|organization_admin|team_admin|user|role_[a-z0-9_]{1,59})$

Responses

  • 200

    The updated organization-level role binding.

    Schema
    RoleBinding
    • emailstringoptional

      Provider profile email when known; never an authorization identifier.

    • display_namestringoptional

      Readable human or service account name when known.

    • kindstringoptional

      Allowed values: "human""service_account"

    • organization_idstringrequired

      pattern ^[a-z][a-z0-9._-]{0,63}$

    • team_idstring or nullrequired

      null for an organization-level binding.

      pattern ^[a-z][a-z0-9._-]{0,63}$

    • user_refstringrequired

      pattern ^[A-Za-z0-9][A-Za-z0-9._:/-]{0,127}$

    • rolestringrequired

      The binding's role: a built-in role id or the id of one of the organization's custom roles.

      pattern ^(ccsio_admin|root|organization_admin|team_admin|user|role_[a-z0-9_]{1,59})$

    • statusstringrequired

      Allowed values: "active""disabled""removed"

    • created_atstring (date-time)required

      RFC 3339, second precision, UTC.

    • updated_atstring (date-time)required

      RFC 3339, second precision, UTC.

  • 400

    Client refusal unrelated to authentication, including malformed input, a denied or failed request.

  • 401

    The request carries no credential, more than one, or one the platform does not accept, and is refused before the operation runs; `error.code` says why. Supply exactly one credential. Codes: invalid-request (no credential, or both Authorization:

    Read more

    Bearer and x-api-key), api-key-invalid (a value that is not a platform API key, or a key of a kind the platform does not accept), api-key-unknown, api-key-revoked, api-key-expired, bootstrap-disabled (the one-shot installation credential, once a key exists), token-malformed (a bearer token that is not a JWT), token-algorithm-unsupported, token-signature-invalid, token-claim-invalid, token-issuer-mismatch, token-audience-mismatch, token-expired, token-not-yet-valid, issuer-untrusted, issuer-residency-mismatch (the issuer belongs to another plane), issuer-resolution-unknown, jwks-unavailable, jwks-key-not-found, staff-token-inactive (a platform operator's token), staff-not-operator, staff-directory-unavailable, identity-not-provisioned (a verified identity with no account on this plane), organization-not-found (a verified identity or key whose organization this plane does not know), internal-error (a fault while the credential is checked is refused too, fail closed), context-cancelled

  • 402

    The organization has to pay first: its standing is payment_required.

    Read more

    The request boundary applies this payment gate to every route except an organization's billing routes, the caller's own context, organization list, onboarding, session report and personal keys, the public routes, and the routes of platform operators, who administer an organization that has to pay. The operations the gate covers declare this response. On /v1 the refusal is rendered in the OpenAI error format. Code: payment-required

  • 403

    The credential is valid but may not do this here; the request is refused by the request boundary before the handler runs, and `error.code` says which refusal. An operation may add codes of its own.

    Read more

    Codes: policy-denied (no role of the caller holds the permission the operation needs, or the credential class may not call it: a personal API key outside inference and MCP, a route that needs a signed-in person, the one-shot installation credential outside its three steps), tenant-mismatch (the organization a path, query, body or X-Tenant header names is not the caller's own), organization-provisioning, organization-suspended, organization-disabled, organization-deleted (the state of the caller's organization), user-disabled, residency-mismatch (the organization lives on another plane), organization-selection-required (a caller with more than one organization, or a platform operator, must name one in X-Organization-Id), organization-not-selectable, no-active-organization-membership, team-not-selectable (the X-Organization-Id or X-Team-Id the caller sent does not name an organization or team it may act in), identity-managed-by-provider (a person who is not a platform operator changes an organization's status, which belongs to the identity provider), support-session-required (a platform operator reads an organization's data without an open support session)

  • 404

    The requested resource or path was not found.

  • 405

    The path is claimed but the request method is not allowed. Go ServeMux returns its standard plain-text response and lists permitted methods in Allow.

  • 409

    The request conflicts with the current state of the resource or with an invariant it protects (a taken name, a role still in use, an organization that must not be deleted, an archived team, the last active root, a seat or service account limit).

  • 500

    Platform failure, rendered without internal cause details.

DELETE/identity/v1/organizations/{org}/members

Remove an organization-level member

Credential
API key
Permission
members.manage

user_ref is a required query parameter (a C0 ref may contain "/" and ":", which a path segment would mangle, as member_ref does on the team members path). Tombstones the row (status removed); re-adding re-activates it.

Read more

A removal takes effect at once: roles are read from the store on every request, never cached. Escalation: the acting principal must be able to manage members and to grant the role the member holds, otherwise 403 membership-forbidden. Removing the last active root is 409 root-required.

curl
curl -X DELETE "https://console.eu.ccsio.ai/identity/v1/organizations/{org}/members?user_ref=<user_ref>" \
  -H "Authorization: Bearer $CCSIO_API_KEY"

Parameters

NameInDescription
X-Request-ID
optional
headerstring

Optional request ULID. A valid ULID (upper or lowercase) is honored; when the header is absent or invalid, the runtime mints the id. The response X-Request-ID header carries the canonical uppercase form.

org
required
pathstring

The organization id (C7 identifier). A value outside the pattern is refused with 400 name-invalid.

user_ref
required
querystring

The target user's C0 ref, query-carried because it may contain "/" and ":".

Responses

  • 200

    The removed (tombstoned) role binding.

    Schema
    RoleBinding
    • emailstringoptional

      Provider profile email when known; never an authorization identifier.

    • display_namestringoptional

      Readable human or service account name when known.

    • kindstringoptional

      Allowed values: "human""service_account"

    • organization_idstringrequired

      pattern ^[a-z][a-z0-9._-]{0,63}$

    • team_idstring or nullrequired

      null for an organization-level binding.

      pattern ^[a-z][a-z0-9._-]{0,63}$

    • user_refstringrequired

      pattern ^[A-Za-z0-9][A-Za-z0-9._:/-]{0,127}$

    • rolestringrequired

      The binding's role: a built-in role id or the id of one of the organization's custom roles.

      pattern ^(ccsio_admin|root|organization_admin|team_admin|user|role_[a-z0-9_]{1,59})$

    • statusstringrequired

      Allowed values: "active""disabled""removed"

    • created_atstring (date-time)required

      RFC 3339, second precision, UTC.

    • updated_atstring (date-time)required

      RFC 3339, second precision, UTC.

  • 400

    Client refusal unrelated to authentication, including malformed input, a denied or failed request.

  • 401

    The request carries no credential, more than one, or one the platform does not accept, and is refused before the operation runs; `error.code` says why. Supply exactly one credential. Codes: invalid-request (no credential, or both Authorization:

    Read more

    Bearer and x-api-key), api-key-invalid (a value that is not a platform API key, or a key of a kind the platform does not accept), api-key-unknown, api-key-revoked, api-key-expired, bootstrap-disabled (the one-shot installation credential, once a key exists), token-malformed (a bearer token that is not a JWT), token-algorithm-unsupported, token-signature-invalid, token-claim-invalid, token-issuer-mismatch, token-audience-mismatch, token-expired, token-not-yet-valid, issuer-untrusted, issuer-residency-mismatch (the issuer belongs to another plane), issuer-resolution-unknown, jwks-unavailable, jwks-key-not-found, staff-token-inactive (a platform operator's token), staff-not-operator, staff-directory-unavailable, identity-not-provisioned (a verified identity with no account on this plane), organization-not-found (a verified identity or key whose organization this plane does not know), internal-error (a fault while the credential is checked is refused too, fail closed), context-cancelled

  • 402

    The organization has to pay first: its standing is payment_required.

    Read more

    The request boundary applies this payment gate to every route except an organization's billing routes, the caller's own context, organization list, onboarding, session report and personal keys, the public routes, and the routes of platform operators, who administer an organization that has to pay. The operations the gate covers declare this response. On /v1 the refusal is rendered in the OpenAI error format. Code: payment-required

  • 403

    The credential is valid but may not do this here; the request is refused by the request boundary before the handler runs, and `error.code` says which refusal. An operation may add codes of its own.

    Read more

    Codes: policy-denied (no role of the caller holds the permission the operation needs, or the credential class may not call it: a personal API key outside inference and MCP, a route that needs a signed-in person, the one-shot installation credential outside its three steps), tenant-mismatch (the organization a path, query, body or X-Tenant header names is not the caller's own), organization-provisioning, organization-suspended, organization-disabled, organization-deleted (the state of the caller's organization), user-disabled, residency-mismatch (the organization lives on another plane), organization-selection-required (a caller with more than one organization, or a platform operator, must name one in X-Organization-Id), organization-not-selectable, no-active-organization-membership, team-not-selectable (the X-Organization-Id or X-Team-Id the caller sent does not name an organization or team it may act in), identity-managed-by-provider (a person who is not a platform operator changes an organization's status, which belongs to the identity provider), support-session-required (a platform operator reads an organization's data without an open support session)

  • 404

    The requested resource or path was not found.

  • 405

    The path is claimed but the request method is not allowed. Go ServeMux returns its standard plain-text response and lists permitted methods in Allow.

  • 409

    The request conflicts with the current state of the resource or with an invariant it protects (a taken name, a role still in use, an organization that must not be deleted, an archived team, the last active root, a seat or service account limit).

  • 500

    Platform failure, rendered without internal cause details.

POST/identity/v1/organizations/{org}/member-invitations

Add a human member by email

Credential
A signed-in person’s token (Console session)
Permission
members.manage
Request body
Body up to 1 MiB

Requires a verified human OIDC session with members.manage and an administrative organization role in the same selected organization. The actor must outrank or equal the requested role and any existing membership role; API keys and bootstrap credentials are refused.

Read more

Reuse the same request_id and body on retries. Durable provider IDs are saved before remote creation and local identities are bound only by exact issuer and subject, never by email. An existing active verified account is added without resetting its password or sending a setup email (member_added). A new human is created without an administrator-chosen password; invitation_sent is returned only after the provider accepts the setup email. Provider verification codes are never persisted or returned. The provider controls the setup link. A completed request cannot resurrect a subsequently removed or disabled membership. Conflicting request reuse, ambiguous email matches or incompatible identities return a generic 409 without disclosing provider details. An organization with no link to the identity provider (one created before the plane linked what an operator creates, and not linked since) cannot have a person created for it: an e-mail the provider already knows (one active, verified human) is still added as member_added, with no provider write, and any other e-mail is refused with 409 organization-identity-unlinked before anything is created (no invitation, no provider human, no user); ask a platform operator to link the organization. A link of another issuer, or one that cannot be read, is still 503. Provider uncertainty or unavailable invitation configuration returns 503; retry the original request. The invited person takes a seat from this moment (there is no acceptance step): when billing is on and the organization has no seat left, the request is refused before anything is created at the provider or locally, with 409 seat-confirmation-required when the plan lets the organization buy one more seat (repeat the request with confirm_extra_seat true once the administrator confirms the extra charge) or 409 seat-limit-reached when it cannot. An existing member who already has access asks nothing.

curl
curl -X POST "https://console.eu.ccsio.ai/identity/v1/organizations/{org}/member-invitations" \
  -H "Authorization: Bearer $CCSIO_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "request_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
  "email": "[email protected]",
  "display_name": "Ben Okafor",
  "role": "user"
}'

Parameters

NameInDescription
X-Request-ID
optional
headerstring

Optional request ULID. A valid ULID (upper or lowercase) is honored; when the header is absent or invalid, the runtime mints the id. The response X-Request-ID header carries the canonical uppercase form.

org
required
pathstring

The organization id (C7 identifier). A value outside the pattern is refused with 400 name-invalid.

Request body application/json

MemberInvitationRequest
  • request_idstring (uuid)required

    Client-generated operation ID preserved together with the same body for retries.

  • emailstring (email)required

    Exact provider email address, at most 200 UTF-8 bytes; used for discovery, not local identity linking.

    1 to 200 characters

  • display_namestringrequired

    Trimmed display name, 1–128 UTF-8 bytes. Used when creating a new human; existing profiles are preserved.

    1 to 128 characters

  • rolestringrequired

    An organization-level role: the built-in root, organization_admin or user, or the id of one of the organization's custom roles. The inviting principal must be able to grant it (anti-escalation). A value that is not an organization-level role id is refused with 400 invalid-request; a well-formed custom role id the organization does not have, with 400 role-invalid.

    pattern ^(root|organization_admin|user|role_[a-z0-9_]{1,59})$

  • confirm_extra_seatbooleanoptional

    Optional (default false): confirms the extra charge when inviting this person needs one more seat than the plan includes (409 seat-confirmation-required without it).

Responses

  • 200

    The member's role binding and the outcome: member_added (membership confirmed, no setup email claimed) or invitation_sent (the provider accepted the setup email).

    Schema
    MemberInvitationResponse
    • statusstringrequired

      member_added confirms membership without claiming a setup email; invitation_sent confirms provider acceptance of the invitation email.

      Allowed values: "member_added""invitation_sent"

    • memberobjectrequired

      A role binding as every member route renders it: the member's role in the organization (team_id null) or in one team, and whether the binding is active, blocked (disabled) or removed. The profile members (email, display_name, kind) are left out when the identity has no profile.

      • emailstringoptional

        Provider profile email when known; never an authorization identifier.

      • display_namestringoptional

        Readable human or service account name when known.

      • kindstringoptional

        Allowed values: "human""service_account"

      • organization_idstringrequired

        pattern ^[a-z][a-z0-9._-]{0,63}$

      • team_idstring or nullrequired

        null for an organization-level binding.

        pattern ^[a-z][a-z0-9._-]{0,63}$

      • user_refstringrequired

        pattern ^[A-Za-z0-9][A-Za-z0-9._:/-]{0,127}$

      • rolestringrequired

        The binding's role: a built-in role id or the id of one of the organization's custom roles.

        pattern ^(ccsio_admin|root|organization_admin|team_admin|user|role_[a-z0-9_]{1,59})$

      • statusstringrequired

        Allowed values: "active""disabled""removed"

      • created_atstring (date-time)required

        RFC 3339, second precision, UTC.

      • updated_atstring (date-time)required

        RFC 3339, second precision, UTC.

  • 400

    Client refusal unrelated to authentication, including malformed input, a denied or failed request.

  • 401

    The request carries no credential, more than one, or one the platform does not accept, and is refused before the operation runs; `error.code` says why. Supply exactly one credential. Codes: invalid-request (no credential, or both Authorization:

    Read more

    Bearer and x-api-key), api-key-invalid (a value that is not a platform API key, or a key of a kind the platform does not accept), api-key-unknown, api-key-revoked, api-key-expired, bootstrap-disabled (the one-shot installation credential, once a key exists), token-malformed (a bearer token that is not a JWT), token-algorithm-unsupported, token-signature-invalid, token-claim-invalid, token-issuer-mismatch, token-audience-mismatch, token-expired, token-not-yet-valid, issuer-untrusted, issuer-residency-mismatch (the issuer belongs to another plane), issuer-resolution-unknown, jwks-unavailable, jwks-key-not-found, staff-token-inactive (a platform operator's token), staff-not-operator, staff-directory-unavailable, identity-not-provisioned (a verified identity with no account on this plane), organization-not-found (a verified identity or key whose organization this plane does not know), internal-error (a fault while the credential is checked is refused too, fail closed), context-cancelled

  • 402

    The organization has to pay first: its standing is payment_required.

    Read more

    The request boundary applies this payment gate to every route except an organization's billing routes, the caller's own context, organization list, onboarding, session report and personal keys, the public routes, and the routes of platform operators, who administer an organization that has to pay. The operations the gate covers declare this response. On /v1 the refusal is rendered in the OpenAI error format. Code: payment-required

  • 403

    The credential is valid but may not do this here; the request is refused by the request boundary before the handler runs, and `error.code` says which refusal. An operation may add codes of its own.

    Read more

    Codes: policy-denied (no role of the caller holds the permission the operation needs, or the credential class may not call it: a personal API key outside inference and MCP, a route that needs a signed-in person, the one-shot installation credential outside its three steps), tenant-mismatch (the organization a path, query, body or X-Tenant header names is not the caller's own), organization-provisioning, organization-suspended, organization-disabled, organization-deleted (the state of the caller's organization), user-disabled, residency-mismatch (the organization lives on another plane), organization-selection-required (a caller with more than one organization, or a platform operator, must name one in X-Organization-Id), organization-not-selectable, no-active-organization-membership, team-not-selectable (the X-Organization-Id or X-Team-Id the caller sent does not name an organization or team it may act in), identity-managed-by-provider (a person who is not a platform operator changes an organization's status, which belongs to the identity provider), support-session-required (a platform operator reads an organization's data without an open support session)

  • 404

    The requested resource or path was not found.

  • 405

    The path is claimed but the request method is not allowed. Go ServeMux returns its standard plain-text response and lists permitted methods in Allow.

  • 409

    The invitation conflicts with the request or with the current identity or membership state, or needs a seat the organization does not have. No provider account details are disclosed. Codes: member-invitation-conflict, seat-confirmation-required, seat-limit-reached, organization-identity-unlinked (the organization is not linked to the identity provider, so new people cannot be invited by e-mail; action: ask a platform operator to link the organization)

  • 500

    Platform failure, rendered without internal cause details.

  • 503

    Provider identity or notification delivery could not be confirmed, or invitations are unavailable. Retry with the original request_id and body. Codes: organization-identity-unavailable (the link to the identity provider cannot be read, or belongs to another issuer), onboarding-unavailable (the plane has no identity provider)

Example response
{
  "status": "invitation_sent",
  "member": {
    "organization_id": "acme",
    "team_id": null,
    "user_ref": "user/onboard/01K7YN2C4D6F8H1K3M5P7R9T0V",
    "role": "user",
    "status": "active",
    "created_at": "2026-10-14T09:50:00Z",
    "updated_at": "2026-10-14T09:50:00Z",
    "email": "[email protected]",
    "display_name": "Ben Okafor",
    "kind": "human"
  }
}
POST/identity/v1/organizations/{org}/members/block

Block an organization member

Credential
API key
Permission
members.manage
Request body
Body up to 1 MiB

Requires members.manage. Sets the member's organization-level membership to disabled (blocked): reversible with POST .../members/unblock, distinct from DELETE .../members which tombstones it.

Read more

A blocked membership authorizes nothing: tenant resolution offers an organization only through ACTIVE memberships, so the member loses it on their very next request on every route - control routes and /v1 alike - and every team membership under it stops counting too; their other organizations are untouched. Same rank rules as a role change: the actor must be able to manage members and to grant the role the target holds (nobody blocks a role above their own). A member cannot block themselves (409 member-self-block). The last active root can never be blocked (409 root-required). Only an active or already-blocked organization-level membership can be blocked (404 membership-not-found otherwise, including a removed one); blocking a blocked member is an idempotent no-op returning the stored row. Sensitive: records a member.blocked security event.

curl
curl -X POST "https://console.eu.ccsio.ai/identity/v1/organizations/{org}/members/block" \
  -H "Authorization: Bearer $CCSIO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "user_ref": "string"
}'
Built from the schema’s required members: replace the values.

Parameters

NameInDescription
X-Request-ID
optional
headerstring

Optional request ULID. A valid ULID (upper or lowercase) is honored; when the header is absent or invalid, the runtime mints the id. The response X-Request-ID header carries the canonical uppercase form.

org
required
pathstring

The organization id (C7 identifier). A value outside the pattern is refused with 400 name-invalid.

Request body application/json

MemberRefRequest
  • user_refstringrequired

    The member's C0 ref.

    pattern ^[A-Za-z0-9][A-Za-z0-9._:/-]{0,127}$

Responses

  • 200

    The member's membership, now disabled.

    Schema
    MemberBinding
    • emailstringoptional

      Provider profile email when known; never an authorization identifier.

    • display_namestringoptional

      Readable human or service account name when known.

    • kindstringoptional

      Allowed values: "human""service_account"

    • organization_idstringrequired

      pattern ^[a-z][a-z0-9._-]{0,63}$

    • team_idstring or nullrequired

      null for an organization-level binding.

      pattern ^[a-z][a-z0-9._-]{0,63}$

    • user_refstringrequired

      pattern ^[A-Za-z0-9][A-Za-z0-9._:/-]{0,127}$

    • rolestringrequired

      The binding's role: a built-in role id or the id of one of the organization's custom roles.

      pattern ^(ccsio_admin|root|organization_admin|team_admin|user|role_[a-z0-9_]{1,59})$

    • statusstringrequired

      Allowed values: "active""disabled""removed"

    • created_atstring (date-time)required

      RFC 3339, second precision, UTC.

    • updated_atstring (date-time)required

      RFC 3339, second precision, UTC.

  • 400

    Client refusal unrelated to authentication, including malformed input, a denied or failed request.

  • 401

    The request carries no credential, more than one, or one the platform does not accept, and is refused before the operation runs; `error.code` says why. Supply exactly one credential. Codes: invalid-request (no credential, or both Authorization:

    Read more

    Bearer and x-api-key), api-key-invalid (a value that is not a platform API key, or a key of a kind the platform does not accept), api-key-unknown, api-key-revoked, api-key-expired, bootstrap-disabled (the one-shot installation credential, once a key exists), token-malformed (a bearer token that is not a JWT), token-algorithm-unsupported, token-signature-invalid, token-claim-invalid, token-issuer-mismatch, token-audience-mismatch, token-expired, token-not-yet-valid, issuer-untrusted, issuer-residency-mismatch (the issuer belongs to another plane), issuer-resolution-unknown, jwks-unavailable, jwks-key-not-found, staff-token-inactive (a platform operator's token), staff-not-operator, staff-directory-unavailable, identity-not-provisioned (a verified identity with no account on this plane), organization-not-found (a verified identity or key whose organization this plane does not know), internal-error (a fault while the credential is checked is refused too, fail closed), context-cancelled

  • 402

    The organization has to pay first: its standing is payment_required.

    Read more

    The request boundary applies this payment gate to every route except an organization's billing routes, the caller's own context, organization list, onboarding, session report and personal keys, the public routes, and the routes of platform operators, who administer an organization that has to pay. The operations the gate covers declare this response. On /v1 the refusal is rendered in the OpenAI error format. Code: payment-required

  • 403

    The credential is valid but may not do this here; the request is refused by the request boundary before the handler runs, and `error.code` says which refusal. An operation may add codes of its own.

    Read more

    Codes: policy-denied (no role of the caller holds the permission the operation needs, or the credential class may not call it: a personal API key outside inference and MCP, a route that needs a signed-in person, the one-shot installation credential outside its three steps), tenant-mismatch (the organization a path, query, body or X-Tenant header names is not the caller's own), organization-provisioning, organization-suspended, organization-disabled, organization-deleted (the state of the caller's organization), user-disabled, residency-mismatch (the organization lives on another plane), organization-selection-required (a caller with more than one organization, or a platform operator, must name one in X-Organization-Id), organization-not-selectable, no-active-organization-membership, team-not-selectable (the X-Organization-Id or X-Team-Id the caller sent does not name an organization or team it may act in), identity-managed-by-provider (a person who is not a platform operator changes an organization's status, which belongs to the identity provider), support-session-required (a platform operator reads an organization's data without an open support session)

  • 404

    The requested resource or path was not found.

  • 405

    The path is claimed but the request method is not allowed. Go ServeMux returns its standard plain-text response and lists permitted methods in Allow.

  • 409

    The request conflicts with the current state of the resource or with an invariant it protects (a taken name, a role still in use, an organization that must not be deleted, an archived team, the last active root, a seat or service account limit).

  • 500

    Platform failure, rendered without internal cause details.

POST/identity/v1/organizations/{org}/members/unblock

Unblock an organization member

Credential
API key
Permission
members.manage
Request body
Body up to 1 MiB

Requires members.manage. Reverses a block: the membership becomes active again with the role it always held, and the member's team memberships count again. The same rank rules as block apply.

Read more

Unblocking an active member is an idempotent no-op returning the stored row; a removed or unknown membership is 404 membership-not-found. Seats: unblocking a human gives them access again and takes one seat. When the seats the plan includes are all used, a self-service organization with a running subscription must confirm the extra seat with confirm_extra_seat true (optional, default false; 409 seat-confirmation-required otherwise, nothing changes); any other organization is refused (409 seat-limit-reached). A service account takes no seat and asks nothing. Sensitive: records a member.unblocked security event.

curl
curl -X POST "https://console.eu.ccsio.ai/identity/v1/organizations/{org}/members/unblock" \
  -H "Authorization: Bearer $CCSIO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "user_ref": "string"
}'
Built from the schema’s required members: replace the values.

Parameters

NameInDescription
X-Request-ID
optional
headerstring

Optional request ULID. A valid ULID (upper or lowercase) is honored; when the header is absent or invalid, the runtime mints the id. The response X-Request-ID header carries the canonical uppercase form.

org
required
pathstring

The organization id (C7 identifier). A value outside the pattern is refused with 400 name-invalid.

Request body application/json

UnblockMemberRequest
  • user_refstringrequired

    The member's C0 ref.

    pattern ^[A-Za-z0-9][A-Za-z0-9._:/-]{0,127}$

  • confirm_extra_seatbooleanoptional

    Optional (default false): confirms the extra charge when unblocking this member needs one more seat than the plan includes.

Responses

  • 200

    The member's membership, now active.

    Schema
    MemberBinding
    • emailstringoptional

      Provider profile email when known; never an authorization identifier.

    • display_namestringoptional

      Readable human or service account name when known.

    • kindstringoptional

      Allowed values: "human""service_account"

    • organization_idstringrequired

      pattern ^[a-z][a-z0-9._-]{0,63}$

    • team_idstring or nullrequired

      null for an organization-level binding.

      pattern ^[a-z][a-z0-9._-]{0,63}$

    • user_refstringrequired

      pattern ^[A-Za-z0-9][A-Za-z0-9._:/-]{0,127}$

    • rolestringrequired

      The binding's role: a built-in role id or the id of one of the organization's custom roles.

      pattern ^(ccsio_admin|root|organization_admin|team_admin|user|role_[a-z0-9_]{1,59})$

    • statusstringrequired

      Allowed values: "active""disabled""removed"

    • created_atstring (date-time)required

      RFC 3339, second precision, UTC.

    • updated_atstring (date-time)required

      RFC 3339, second precision, UTC.

  • 400

    Client refusal unrelated to authentication, including malformed input, a denied or failed request.

  • 401

    The request carries no credential, more than one, or one the platform does not accept, and is refused before the operation runs; `error.code` says why. Supply exactly one credential. Codes: invalid-request (no credential, or both Authorization:

    Read more

    Bearer and x-api-key), api-key-invalid (a value that is not a platform API key, or a key of a kind the platform does not accept), api-key-unknown, api-key-revoked, api-key-expired, bootstrap-disabled (the one-shot installation credential, once a key exists), token-malformed (a bearer token that is not a JWT), token-algorithm-unsupported, token-signature-invalid, token-claim-invalid, token-issuer-mismatch, token-audience-mismatch, token-expired, token-not-yet-valid, issuer-untrusted, issuer-residency-mismatch (the issuer belongs to another plane), issuer-resolution-unknown, jwks-unavailable, jwks-key-not-found, staff-token-inactive (a platform operator's token), staff-not-operator, staff-directory-unavailable, identity-not-provisioned (a verified identity with no account on this plane), organization-not-found (a verified identity or key whose organization this plane does not know), internal-error (a fault while the credential is checked is refused too, fail closed), context-cancelled

  • 402

    The organization has to pay first: its standing is payment_required.

    Read more

    The request boundary applies this payment gate to every route except an organization's billing routes, the caller's own context, organization list, onboarding, session report and personal keys, the public routes, and the routes of platform operators, who administer an organization that has to pay. The operations the gate covers declare this response. On /v1 the refusal is rendered in the OpenAI error format. Code: payment-required

  • 403

    The credential is valid but may not do this here; the request is refused by the request boundary before the handler runs, and `error.code` says which refusal. An operation may add codes of its own.

    Read more

    Codes: policy-denied (no role of the caller holds the permission the operation needs, or the credential class may not call it: a personal API key outside inference and MCP, a route that needs a signed-in person, the one-shot installation credential outside its three steps), tenant-mismatch (the organization a path, query, body or X-Tenant header names is not the caller's own), organization-provisioning, organization-suspended, organization-disabled, organization-deleted (the state of the caller's organization), user-disabled, residency-mismatch (the organization lives on another plane), organization-selection-required (a caller with more than one organization, or a platform operator, must name one in X-Organization-Id), organization-not-selectable, no-active-organization-membership, team-not-selectable (the X-Organization-Id or X-Team-Id the caller sent does not name an organization or team it may act in), identity-managed-by-provider (a person who is not a platform operator changes an organization's status, which belongs to the identity provider), support-session-required (a platform operator reads an organization's data without an open support session)

  • 404

    The requested resource or path was not found.

  • 405

    The path is claimed but the request method is not allowed. Go ServeMux returns its standard plain-text response and lists permitted methods in Allow.

  • 409

    The request conflicts with the current state of the resource or with an invariant it protects (a taken name, a role still in use, an organization that must not be deleted, an archived team, the last active root, a seat or service account limit).

  • 500

    Platform failure, rendered without internal cause details.

POST/identity/v1/organizations/{org}/members/transfer

Move a member to another organization

Credential
API key
Permission
members.transfer
Request body
Body up to 1 MiB

Moves one member from the route's organization (the source) to target_org in ONE database transaction: the member's organization-level membership and every team membership under it are removed in the source, and an active organization-level membership with the requested role (default user) is created in the target.

Read more

Either both happen or neither. Authority: members.transfer in BOTH organizations - held by the Root built-in role alone, so organization_admin, team_admin and user are refused (403 policy-denied) and no custom role can carry it - or a platform ccsio_admin. The target organization's role-assignment rules apply - the actor must be able to grant the role in the target, and a custom role id is the TARGET organization's. The member takes a seat in the TARGET organization and the source's seat is released; confirm_extra_seat is optional (default false) and confirms the extra seat in the TARGET organization, under the rule that applies when a human with no access to the target joins it: when the seats the target's plan includes are all used, a self-service target with a running subscription must have the extra seat confirmed (409 seat-confirmation-required otherwise, nothing changes) and any other target is refused (409 seat-limit-reached). Refused: a user who is not an active member of the source (404 membership-not-found); a blocked member (409 membership-disabled - a transfer must not lift a block); the last active root of the source (409 root-required); a target that does not exist or is not active (409 transfer-target-unavailable); a user who already holds any non-removed membership of the target at any level (409 member-exists); the same organization on both sides (400 invalid-request). A removed tombstone in the target is overwritten with the requested role, never resurrected with its old one. The response is the member's new membership in the target. Sensitive: records an organization.member_transferred_out security event in the source organization and an organization.member_transferred_in event in the target, sharing one correlation_id and naming each other in counterpart_org_id.

curl
curl -X POST "https://console.eu.ccsio.ai/identity/v1/organizations/{org}/members/transfer" \
  -H "Authorization: Bearer $CCSIO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "user_ref": "string",
  "target_org": "string"
}'
Built from the schema’s required members: replace the values.

Parameters

NameInDescription
X-Request-ID
optional
headerstring

Optional request ULID. A valid ULID (upper or lowercase) is honored; when the header is absent or invalid, the runtime mints the id. The response X-Request-ID header carries the canonical uppercase form.

org
required
pathstring

The organization id (C7 identifier). A value outside the pattern is refused with 400 name-invalid.

Request body application/json

TransferMemberRequest
  • user_refstringrequired

    The member to move.

    pattern ^[A-Za-z0-9][A-Za-z0-9._:/-]{0,127}$

  • target_orgstringrequired

    The organization the member joins; it must exist, be active and not already hold the user in any non-removed membership.

    pattern ^[a-z][a-z0-9._-]{0,63}$

  • rolestringoptional

    Optional (default user): the member's organization-level role in the TARGET organization - a built-in organization role or the id of one of the TARGET organization's custom roles. Subject to the target organization's role-assignment rules: the actor must be able to grant it there.

    pattern ^(root|organization_admin|user|role_[a-z0-9_]{1,59})$

  • confirm_extra_seatbooleanoptional

    Optional (default false): confirms the extra charge when the member needs one more seat than the TARGET organization's plan includes.

Responses

  • 200

    The member's new, active organization-level membership in the target organization.

    Schema
    MemberBinding
    • emailstringoptional

      Provider profile email when known; never an authorization identifier.

    • display_namestringoptional

      Readable human or service account name when known.

    • kindstringoptional

      Allowed values: "human""service_account"

    • organization_idstringrequired

      pattern ^[a-z][a-z0-9._-]{0,63}$

    • team_idstring or nullrequired

      null for an organization-level binding.

      pattern ^[a-z][a-z0-9._-]{0,63}$

    • user_refstringrequired

      pattern ^[A-Za-z0-9][A-Za-z0-9._:/-]{0,127}$

    • rolestringrequired

      The binding's role: a built-in role id or the id of one of the organization's custom roles.

      pattern ^(ccsio_admin|root|organization_admin|team_admin|user|role_[a-z0-9_]{1,59})$

    • statusstringrequired

      Allowed values: "active""disabled""removed"

    • created_atstring (date-time)required

      RFC 3339, second precision, UTC.

    • updated_atstring (date-time)required

      RFC 3339, second precision, UTC.

  • 400

    Client refusal unrelated to authentication, including malformed input, a denied or failed request.

  • 401

    The request carries no credential, more than one, or one the platform does not accept, and is refused before the operation runs; `error.code` says why. Supply exactly one credential. Codes: invalid-request (no credential, or both Authorization:

    Read more

    Bearer and x-api-key), api-key-invalid (a value that is not a platform API key, or a key of a kind the platform does not accept), api-key-unknown, api-key-revoked, api-key-expired, bootstrap-disabled (the one-shot installation credential, once a key exists), token-malformed (a bearer token that is not a JWT), token-algorithm-unsupported, token-signature-invalid, token-claim-invalid, token-issuer-mismatch, token-audience-mismatch, token-expired, token-not-yet-valid, issuer-untrusted, issuer-residency-mismatch (the issuer belongs to another plane), issuer-resolution-unknown, jwks-unavailable, jwks-key-not-found, staff-token-inactive (a platform operator's token), staff-not-operator, staff-directory-unavailable, identity-not-provisioned (a verified identity with no account on this plane), organization-not-found (a verified identity or key whose organization this plane does not know), internal-error (a fault while the credential is checked is refused too, fail closed), context-cancelled

  • 402

    The organization has to pay first: its standing is payment_required.

    Read more

    The request boundary applies this payment gate to every route except an organization's billing routes, the caller's own context, organization list, onboarding, session report and personal keys, the public routes, and the routes of platform operators, who administer an organization that has to pay. The operations the gate covers declare this response. On /v1 the refusal is rendered in the OpenAI error format. Code: payment-required

  • 403

    The credential is valid but may not do this here; the request is refused by the request boundary before the handler runs, and `error.code` says which refusal. An operation may add codes of its own.

    Read more

    Codes: policy-denied (no role of the caller holds the permission the operation needs, or the credential class may not call it: a personal API key outside inference and MCP, a route that needs a signed-in person, the one-shot installation credential outside its three steps), tenant-mismatch (the organization a path, query, body or X-Tenant header names is not the caller's own), organization-provisioning, organization-suspended, organization-disabled, organization-deleted (the state of the caller's organization), user-disabled, residency-mismatch (the organization lives on another plane), organization-selection-required (a caller with more than one organization, or a platform operator, must name one in X-Organization-Id), organization-not-selectable, no-active-organization-membership, team-not-selectable (the X-Organization-Id or X-Team-Id the caller sent does not name an organization or team it may act in), identity-managed-by-provider (a person who is not a platform operator changes an organization's status, which belongs to the identity provider), support-session-required (a platform operator reads an organization's data without an open support session)

  • 404

    The requested resource or path was not found.

  • 405

    The path is claimed but the request method is not allowed. Go ServeMux returns its standard plain-text response and lists permitted methods in Allow.

  • 409

    The request conflicts with the current state of the resource or with an invariant it protects (a taken name, a role still in use, an organization that must not be deleted, an archived team, the last active root, a seat or service account limit).

  • 500

    Platform failure, rendered without internal cause details.

  • 503

    A dependency the operation needs is not configured on this plane or could not be reached, and nothing was changed. `error.code` names it; an operation lists the ones it can answer besides the boundary's. Retry later. Codes: support-audit-unavailable (the request boundary: an operator's read under an open support session could not be recorded, so nothing was served)

GET/identity/v1/organizations/{org}/members/transfer-targets

List the organizations a member may be moved to

Credential
API key
Permission
members.transfer

Requires members.transfer in the route's organization (the permission of POST .../members/transfer, with the same refusal: only the organization's root, or a platform ccsio_admin, holds it).

Read more

Lists the ACTIVE organizations other than the route's where the caller also holds members.transfer through an active organization-level role binding (a caller holding it at platform level lists every active organization), ordered by display name and then id: the organizations POST .../members/transfer would accept as target_org for this caller, as far as the caller's own authority goes (whether a given member can move there, for instance one who already belongs to it, is still the transfer's to decide). It reads this plane's own data only and asks the identity provider nothing, so it answers quickly where GET /identity/v1/self/organizations does not.

curl
curl "https://console.eu.ccsio.ai/identity/v1/organizations/{org}/members/transfer-targets" \
  -H "Authorization: Bearer $CCSIO_API_KEY"

Parameters

NameInDescription
X-Request-ID
optional
headerstring

Optional request ULID. A valid ULID (upper or lowercase) is honored; when the header is absent or invalid, the runtime mints the id. The response X-Request-ID header carries the canonical uppercase form.

org
required
pathstring

The organization id (C7 identifier). A value outside the pattern is refused with 400 name-invalid.

Responses

  • 200

    The organizations the caller may move a member to.

    Schema
    TransferTargetsResponse
    • organizationsarray of TransferTargetrequired
      • organization_idstringrequired

        pattern ^[a-z][a-z0-9._-]{0,63}$

      • display_namestringrequired

        1 to 128 characters

  • 400

    Client refusal unrelated to authentication, including malformed input, a denied or failed request.

  • 401

    The request carries no credential, more than one, or one the platform does not accept, and is refused before the operation runs; `error.code` says why. Supply exactly one credential. Codes: invalid-request (no credential, or both Authorization:

    Read more

    Bearer and x-api-key), api-key-invalid (a value that is not a platform API key, or a key of a kind the platform does not accept), api-key-unknown, api-key-revoked, api-key-expired, bootstrap-disabled (the one-shot installation credential, once a key exists), token-malformed (a bearer token that is not a JWT), token-algorithm-unsupported, token-signature-invalid, token-claim-invalid, token-issuer-mismatch, token-audience-mismatch, token-expired, token-not-yet-valid, issuer-untrusted, issuer-residency-mismatch (the issuer belongs to another plane), issuer-resolution-unknown, jwks-unavailable, jwks-key-not-found, staff-token-inactive (a platform operator's token), staff-not-operator, staff-directory-unavailable, identity-not-provisioned (a verified identity with no account on this plane), organization-not-found (a verified identity or key whose organization this plane does not know), internal-error (a fault while the credential is checked is refused too, fail closed), context-cancelled

  • 402

    The organization has to pay first: its standing is payment_required.

    Read more

    The request boundary applies this payment gate to every route except an organization's billing routes, the caller's own context, organization list, onboarding, session report and personal keys, the public routes, and the routes of platform operators, who administer an organization that has to pay. The operations the gate covers declare this response. On /v1 the refusal is rendered in the OpenAI error format. Code: payment-required

  • 403

    The credential is valid but may not do this here; the request is refused by the request boundary before the handler runs, and `error.code` says which refusal. An operation may add codes of its own.

    Read more

    Codes: policy-denied (no role of the caller holds the permission the operation needs, or the credential class may not call it: a personal API key outside inference and MCP, a route that needs a signed-in person, the one-shot installation credential outside its three steps), tenant-mismatch (the organization a path, query, body or X-Tenant header names is not the caller's own), organization-provisioning, organization-suspended, organization-disabled, organization-deleted (the state of the caller's organization), user-disabled, residency-mismatch (the organization lives on another plane), organization-selection-required (a caller with more than one organization, or a platform operator, must name one in X-Organization-Id), organization-not-selectable, no-active-organization-membership, team-not-selectable (the X-Organization-Id or X-Team-Id the caller sent does not name an organization or team it may act in), identity-managed-by-provider (a person who is not a platform operator changes an organization's status, which belongs to the identity provider), support-session-required (a platform operator reads an organization's data without an open support session)

  • 404

    The requested resource or path was not found.

  • 405

    The path is claimed but the request method is not allowed. Go ServeMux returns its standard plain-text response and lists permitted methods in Allow.

  • 500

    Platform failure, rendered without internal cause details.

  • 503

    A dependency the operation needs is not configured on this plane or could not be reached, and nothing was changed. `error.code` names it; an operation lists the ones it can answer besides the boundary's. Retry later. Codes: support-audit-unavailable (the request boundary: an operator's read under an open support session could not be recorded, so nothing was served)

POST/identity/v1/organizations/{org}/members/password-reset

Email a member a link to set a new password

Credential
API key
Permission
members.manage
Request body
Body up to 1 MiB

Requires members.manage. Asks the identity provider to email the member a link to set a new password (Zitadel's password reset with an emailed link); the platform never sees, sets or stores a password, and the response does not say whether the person ever follows the link.

Read more

Same rank and target rules as blocking a member: the actor must be able to manage members and to grant the role the target holds (an administrator cannot act on a root); a person who is not a member of the organization, or whose membership was removed, is 404 membership-not-found; a service account, or a person who does not sign in with a password through this plane's identity provider (a single sign-on account), is refused with 409 password-reset-unavailable, which the provider's own refusal of the account maps to as well. Answers 202 with the member's user_ref and sent true: the provider has been asked to send the email. 503 organization-identity-unavailable when the identity provider cannot be reached or does not confirm the user, and 503 onboarding-unavailable when the plane has no identity provider. Sensitive: records a member.password_reset_sent security event (the member is the item and the subject; nothing of the link is recorded).

curl
curl -X POST "https://console.eu.ccsio.ai/identity/v1/organizations/{org}/members/password-reset" \
  -H "Authorization: Bearer $CCSIO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "user_ref": "string"
}'
Built from the schema’s required members: replace the values.

Parameters

NameInDescription
X-Request-ID
optional
headerstring

Optional request ULID. A valid ULID (upper or lowercase) is honored; when the header is absent or invalid, the runtime mints the id. The response X-Request-ID header carries the canonical uppercase form.

org
required
pathstring

The organization id (C7 identifier). A value outside the pattern is refused with 400 name-invalid.

Request body application/json

MemberRefRequest
  • user_refstringrequired

    The member's C0 ref.

    pattern ^[A-Za-z0-9][A-Za-z0-9._:/-]{0,127}$

Responses

  • 202

    The identity provider was asked to email the member the link.

    Schema
    MemberNotice
    • user_refstringrequired

      The member's C0 ref.

      pattern ^[A-Za-z0-9][A-Za-z0-9._:/-]{0,127}$

    • sentbooleanrequired

      Always true: the identity provider was asked to send the email. It does not say the person received or followed it.

      Allowed values: true

  • 400

    Client refusal unrelated to authentication, including malformed input, a denied or failed request.

  • 401

    The request carries no credential, more than one, or one the platform does not accept, and is refused before the operation runs; `error.code` says why. Supply exactly one credential. Codes: invalid-request (no credential, or both Authorization:

    Read more

    Bearer and x-api-key), api-key-invalid (a value that is not a platform API key, or a key of a kind the platform does not accept), api-key-unknown, api-key-revoked, api-key-expired, bootstrap-disabled (the one-shot installation credential, once a key exists), token-malformed (a bearer token that is not a JWT), token-algorithm-unsupported, token-signature-invalid, token-claim-invalid, token-issuer-mismatch, token-audience-mismatch, token-expired, token-not-yet-valid, issuer-untrusted, issuer-residency-mismatch (the issuer belongs to another plane), issuer-resolution-unknown, jwks-unavailable, jwks-key-not-found, staff-token-inactive (a platform operator's token), staff-not-operator, staff-directory-unavailable, identity-not-provisioned (a verified identity with no account on this plane), organization-not-found (a verified identity or key whose organization this plane does not know), internal-error (a fault while the credential is checked is refused too, fail closed), context-cancelled

  • 402

    The organization has to pay first: its standing is payment_required.

    Read more

    The request boundary applies this payment gate to every route except an organization's billing routes, the caller's own context, organization list, onboarding, session report and personal keys, the public routes, and the routes of platform operators, who administer an organization that has to pay. The operations the gate covers declare this response. On /v1 the refusal is rendered in the OpenAI error format. Code: payment-required

  • 403

    The credential is valid but may not do this here; the request is refused by the request boundary before the handler runs, and `error.code` says which refusal. An operation may add codes of its own.

    Read more

    Codes: policy-denied (no role of the caller holds the permission the operation needs, or the credential class may not call it: a personal API key outside inference and MCP, a route that needs a signed-in person, the one-shot installation credential outside its three steps), tenant-mismatch (the organization a path, query, body or X-Tenant header names is not the caller's own), organization-provisioning, organization-suspended, organization-disabled, organization-deleted (the state of the caller's organization), user-disabled, residency-mismatch (the organization lives on another plane), organization-selection-required (a caller with more than one organization, or a platform operator, must name one in X-Organization-Id), organization-not-selectable, no-active-organization-membership, team-not-selectable (the X-Organization-Id or X-Team-Id the caller sent does not name an organization or team it may act in), identity-managed-by-provider (a person who is not a platform operator changes an organization's status, which belongs to the identity provider), support-session-required (a platform operator reads an organization's data without an open support session)

  • 404

    The requested resource or path was not found.

  • 405

    The path is claimed but the request method is not allowed. Go ServeMux returns its standard plain-text response and lists permitted methods in Allow.

  • 409

    The request conflicts with the current state of the resource or with an invariant it protects (a taken name, a role still in use, an organization that must not be deleted, an archived team, the last active root, a seat or service account limit).

  • 500

    Platform failure, rendered without internal cause details.

  • 503

    A dependency the operation needs is not configured on this plane or could not be reached, and nothing was changed. `error.code` names it; an operation lists the ones it can answer besides the boundary's. Retry later. Codes: support-audit-unavailable (the request boundary: an operator's read under an open support session could not be recorded, so nothing was served)

POST/identity/v1/organizations/{org}/member-invitations/resend

Send a member's invitation again

Credential
API key
Permission
members.manage
Request body
Body up to 1 MiB

Requires members.manage. Sends the identity provider's invitation email again to a member who has not set their account up (the person the provider still holds as invited and unverified). The platform stores no invitation code.

Read more

Same rank and target rules as blocking a member: the actor must be able to manage members and to grant the role the target holds; a person who is not a member of the organization, or whose membership was removed, is 404 membership-not-found. A member whose account is already active or verified, a service account, and a person who is not an invitee of this plane's identity provider have nothing pending: 409 invitation-not-pending. Answers 202 with the member's user_ref and sent true: the provider has been asked to send the invitation. 503 organization-identity-unavailable when the identity provider cannot be reached or does not confirm the user, and 503 onboarding-unavailable when the plane has no identity provider. Sensitive: records a member.invitation_resent security event (the member is the item and the subject).

curl
curl -X POST "https://console.eu.ccsio.ai/identity/v1/organizations/{org}/member-invitations/resend" \
  -H "Authorization: Bearer $CCSIO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "user_ref": "string"
}'
Built from the schema’s required members: replace the values.

Parameters

NameInDescription
X-Request-ID
optional
headerstring

Optional request ULID. A valid ULID (upper or lowercase) is honored; when the header is absent or invalid, the runtime mints the id. The response X-Request-ID header carries the canonical uppercase form.

org
required
pathstring

The organization id (C7 identifier). A value outside the pattern is refused with 400 name-invalid.

Request body application/json

MemberRefRequest
  • user_refstringrequired

    The member's C0 ref.

    pattern ^[A-Za-z0-9][A-Za-z0-9._:/-]{0,127}$

Responses

  • 202

    The identity provider was asked to send the invitation again.

    Schema
    MemberNotice
    • user_refstringrequired

      The member's C0 ref.

      pattern ^[A-Za-z0-9][A-Za-z0-9._:/-]{0,127}$

    • sentbooleanrequired

      Always true: the identity provider was asked to send the email. It does not say the person received or followed it.

      Allowed values: true

  • 400

    Client refusal unrelated to authentication, including malformed input, a denied or failed request.

  • 401

    The request carries no credential, more than one, or one the platform does not accept, and is refused before the operation runs; `error.code` says why. Supply exactly one credential. Codes: invalid-request (no credential, or both Authorization:

    Read more

    Bearer and x-api-key), api-key-invalid (a value that is not a platform API key, or a key of a kind the platform does not accept), api-key-unknown, api-key-revoked, api-key-expired, bootstrap-disabled (the one-shot installation credential, once a key exists), token-malformed (a bearer token that is not a JWT), token-algorithm-unsupported, token-signature-invalid, token-claim-invalid, token-issuer-mismatch, token-audience-mismatch, token-expired, token-not-yet-valid, issuer-untrusted, issuer-residency-mismatch (the issuer belongs to another plane), issuer-resolution-unknown, jwks-unavailable, jwks-key-not-found, staff-token-inactive (a platform operator's token), staff-not-operator, staff-directory-unavailable, identity-not-provisioned (a verified identity with no account on this plane), organization-not-found (a verified identity or key whose organization this plane does not know), internal-error (a fault while the credential is checked is refused too, fail closed), context-cancelled

  • 402

    The organization has to pay first: its standing is payment_required.

    Read more

    The request boundary applies this payment gate to every route except an organization's billing routes, the caller's own context, organization list, onboarding, session report and personal keys, the public routes, and the routes of platform operators, who administer an organization that has to pay. The operations the gate covers declare this response. On /v1 the refusal is rendered in the OpenAI error format. Code: payment-required

  • 403

    The credential is valid but may not do this here; the request is refused by the request boundary before the handler runs, and `error.code` says which refusal. An operation may add codes of its own.

    Read more

    Codes: policy-denied (no role of the caller holds the permission the operation needs, or the credential class may not call it: a personal API key outside inference and MCP, a route that needs a signed-in person, the one-shot installation credential outside its three steps), tenant-mismatch (the organization a path, query, body or X-Tenant header names is not the caller's own), organization-provisioning, organization-suspended, organization-disabled, organization-deleted (the state of the caller's organization), user-disabled, residency-mismatch (the organization lives on another plane), organization-selection-required (a caller with more than one organization, or a platform operator, must name one in X-Organization-Id), organization-not-selectable, no-active-organization-membership, team-not-selectable (the X-Organization-Id or X-Team-Id the caller sent does not name an organization or team it may act in), identity-managed-by-provider (a person who is not a platform operator changes an organization's status, which belongs to the identity provider), support-session-required (a platform operator reads an organization's data without an open support session)

  • 404

    The requested resource or path was not found.

  • 405

    The path is claimed but the request method is not allowed. Go ServeMux returns its standard plain-text response and lists permitted methods in Allow.

  • 409

    The request conflicts with the current state of the resource or with an invariant it protects (a taken name, a role still in use, an organization that must not be deleted, an archived team, the last active root, a seat or service account limit).

  • 500

    Platform failure, rendered without internal cause details.

  • 503

    A dependency the operation needs is not configured on this plane or could not be reached, and nothing was changed. `error.code` names it; an operation lists the ones it can answer besides the boundary's. Retry later. Codes: support-audit-unavailable (the request boundary: an operator's read under an open support session could not be recorded, so nothing was served)

Generated from the platform contracts at commit 5f833620.

Explore the platform

Get your first API key

Registration is open. Four steps to your first call: create your account, create your organization, create your API key, and start using it.

  1. 01Create your account
  2. 02Create your organization
  3. 03Create your API key
  4. 04Start using it