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

Service accounts

The service accounts an API key acts as.

Documentation menu

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

POST/identity/v1/service-accounts

Create a service account in the organization

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

Requires members.manage and authority to grant the chosen role. role is optional (default user): a built-in organization-level role other than root, or the id of one of the organization's custom roles; the caller must be able to grant it (anti-escalation: a custom-role holder can never grant organization_admin, and any role's permissions must be a subset of the caller's own).

Read more

Creates the service account and its organization membership atomically. The server generates the stable principal reference; the caller supplies the organization, the display name and optionally the role. The new identity cannot receive human or platform-administrator authority through this operation. A service account is not a seat, but the plan limits how many an organization may have (a platform operator may set another limit): at the limit the request is refused and nothing can be bought.

curl
curl -X POST "https://console.us.ccsio.ai/identity/v1/service-accounts" \
  -H "Authorization: Bearer $CCSIO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "org_id": "acme",
  "display_name": "billing-app",
  "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.

Request body application/json

CreateServiceAccountRequest
  • org_idstringrequired

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

  • display_namestringrequired

    Service-account display name, 1 to 128 bytes.

    1 to 128 characters

  • rolestringoptional

    Optional (default user): a built-in organization-level role other than root, or the id of one of the organization's custom roles. Subject to the anti-escalation rule: the caller must be able to grant it. root and team_admin are refused.

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

Responses

  • 201

    The created service account, ready for API-key issuance.

    Schema
    APIKeyPrincipal
    • principal_refstringrequired

      Stable service-account reference sent as principal_ref when issuing a key.

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

    • display_namestringrequired
    • kindstringrequired

      always "service_account"

  • 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
{
  "principal_ref": "svc/01K7YP2C9W4X5E8H3J6M0N1Q2R",
  "display_name": "billing-app",
  "kind": "service_account"
}

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