Identity & Access Management

Preview — pending review

This reference is generated from the platform API contract and is still under review. Operations, fields, and descriptions can change before publication.

Open a new subscription (with its default project) under the tenant

POST
/tenants/{tenantId}/subscriptions

Creates a subscription (billing account) beneath the tenant and, in the SAME transaction, its default project core (: a subscription is never created without a project). The subscription itself is a pure catalog row and is returned at once (201); the default project provisions its Keystone project asynchronously, tracked by provisioningOperationId (always present -- poll GET /operations/{operationId}). The subscription id is derived from the tenant id + the slugified name (numeric suffix on collision) and never changes. Authorization: the caller must be an OWNER OF THE TENANT (a tenant-kind owner grant, -- owning one subscription or project is not enough): reached-but-not-owner is 403, an unknown/unreached tenant 404. An API token needs BOTH the iam:write and the billing:write action scopes, as a subscription is a billing account -- missing either is 403 TOKEN_SCOPE_MISSING before the tenant is resolved and nothing is created (iam:write is checked first). A service-account key is refused 403 INTERACTIVE_SESSION_REQUIRED whatever its scopes (an SA key never performs an iam:write action). A console session is gated by the owner role alone. A tenant on non-payment hold is refused 403 TENANT_SUSPENDED. Validation: name must be ASCII and contain a letter or digit (422, field=name); currency is optional and USD-only (any other value 422 field=currency, details.supportedCurrencies); billingCountry is REQUIRED and must be an allowed country (GET /tenants/{tenantId}/billing-countries; otherwise 422 field=billingCountry, details.allowedBillingCountries); an unknown body field is 422. The tenant's subscription cap (max_subscriptions_per_tenant) and the per-subscription project cap are enforced in the same transaction -- 409 QUOTA_EXCEEDED, nothing is created. Async & state: subscription synchronous; default project PENDING → provisioned by the iam.scope.provision Operation. Errors: 401; 403 not a tenant owner / token scope (iam:write, billing:write) / service-account key / tenant on hold; 404 tenant not reached; 409 QUOTA_EXCEEDED or an Idempotency-Key reused with a different body (CONFLICT); 422 validation (including a non-UUID Idempotency-Key); 500. Idempotency/Concurrency: Idempotency-Key (UUID) is optional (recommended); a replay returns the original 201 without minting a second subscription; concurrent same-key requests collapse to one.

Authorization

bearerToken
headerAuthorizationBearer <token>

An API token (pc_live_…) or a service-account key (sak_live_…), created in Identity & Access Management and sent as Authorization: Bearer <token>. Requests are rate limited per credential and per tenant: every response carries X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset, and a refused request gets 429 RATE_LIMITED with Retry-After.

Path Parameters

tenantId*string

The tenant id.

Header Parameters

Idempotency-Key?string

Optional; recommended for safe retries. When sent, the same key+body within 24h replays the original result and the same key with a different body is 409 CONFLICT; keys are unique per tenant. When an API token or service-account (bearer) caller omits it, the request is applied once with no replay protection (a retry may apply it again). A console session gets one from the edge.

Formatuuid

Request Body

application/json
  1. body

Body of POST /tenants/{tenantId}/subscriptions. The default core project is always created; there is no flag for it.

name*string

Display name; ASCII, at least one letter or digit. Also seeds the (immutable) subscription id.

region*string

The subscription's defaultRegion -- the region its default project (and every later project) provisions into.

currency?|

Optional; USD only. Omitted or null means USD; any other value is 422.

billingCountry*string

ISO 3166-1 alpha-2 billing country; must be one of GET /tenants/{tenantId}/billing-countries.

Match^[A-Z]{2}$

Response Body

The created subscription and its default project's provisioning Operation id.

application/json
  1. response

The 201 body of a subscription create.

subscription*

Subscription summary.

provisioningOperationId*string

The PENDING iam.scope.provision Operation of the default core project; always present.

curl -X POST "https://example.com/tenants/string/subscriptions" \  -H "Content-Type: application/json" \  -d '{    "name": "string",    "region": "string",    "billingCountry": "string"  }'
{  "subscription": {    "id": "string",    "tenantId": "string",    "name": "string",    "currency": "USD",    "defaultRegion": "string",    "billingCountry": "string",    "pendingBillingCountry": {      "country": "string",      "effectiveFrom": "2019-08-24T14:15:22Z"    }  },  "provisioningOperationId": "string"}