Billing & FinOps

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.

Buy a subscription-scoped add-on / licence entitlement

POST
/scopes/{scopeId}/billing/entitlements

Buys one subscription-scoped catalog add-on or licence as an account-level entitlement. The chosen period's catalog price is FROZEN at purchase (a later catalog price change never re-prices this entitlement) and one immutable rate-card version is written for the entitlement's own SKU, so the existing rater prices its metered usage unchanged. quantity is the SEAT POOL size: an entitlement with quantity: N can be assigned to N DISTINCT resources at the same time, and seats can be released and transferred between them. No operator approval is required and nothing is charged at purchase. An entitlement is post-paid through the usage ledger exactly like an instance-scoped add-on: the charge reaches the customer on the next invoice, where the existing operator settlement gate applies. Validation: itemKind must be addon or license; itemId must reference an ACTIVE catalog item whose attachScope is subscription — an instance-scoped item is refused 422 VALIDATION_FAILED on field attachScope (the mirror of the refusal instance-create raises for a subscription-scoped item); period must be one of hour|month|year AND priced by the operator for that item (else 422 on field period); quantity must be an integer between 1 and 1000. Unknown or inactive item → 404 NOT_FOUND. Caller needs billing:write (owner|admin|billing-ops), else 403. Async & state: Synchronous — returns 201 with the created entitlement. No Operation is minted: there is no provider call to track. Errors: 401 unauthenticated; 403 insufficient role; 404 unknown scope or catalog item; 422 field validation failure including the attach-scope mismatch; 500 internal failure. Idempotency/Concurrency: Not idempotent — each call buys another entitlement. Clients that must retry safely should read the list first.

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

scopeId*string

Opaque ownership+authorization scope resolving to tenant + subscription + project.

Request Body

application/json
  1. body
itemKind*string
Value in"addon""license"
itemId*string

A GLOBAL catalog item whose attachScope is subscription. An instance-scoped item is refused with 422 on field attachScope — buy those in the instance-create wizard.

period*string

Must be a period the operator priced for this item.

Value in"hour""month""year"
quantity?integer

The seat POOL size — how many distinct resources may hold this entitlement simultaneously. Multiplies the billed amount every period.

Range1 <= value <= 1000
Default1

Response Body

The purchased entitlement, with its first term open and no seats assigned.

application/json
  1. response
data*

A subscription-scoped add-on or licence the account HOLDS, independent of any one resource. Unlike an instance-scoped add-on (which is born with a VM and dies with it), an entitlement survives the deletion of every resource it was applied to and can be re-applied elsewhere. quantity is a POOL OF SEATS: an entitlement with quantity: N may be assigned to N DISTINCT resources at the same time. Billing charges quantity units per period whether or not every seat is currently assigned — the customer bought the pool, not the occupancy.

curl -X POST "https://example.com/scopes/string/billing/entitlements" \  -H "Content-Type: application/json" \  -d '{    "itemKind": "addon",    "itemId": "string",    "period": "hour"  }'
{  "data": {    "id": "string",    "itemKind": "addon",    "itemId": "string",    "itemSlug": "string",    "name": "string",    "period": "hour",    "unitPriceMinor": 0,    "currency": "string",    "sku": "string",    "quantity": 1,    "seatsUsed": 0,    "seatsAvailable": 0,    "state": "active",    "autoRenew": true,    "honoured": true,    "termStartedAt": "2019-08-24T14:15:22Z",    "termEndsAt": "2019-08-24T14:15:22Z",    "renewsAt": "2019-08-24T14:15:22Z",    "createdAt": "2019-08-24T14:15:22Z",    "cancelledAt": "2019-08-24T14:15:22Z",    "expiredAt": "2019-08-24T14:15:22Z",    "assignments": [      {        "id": "string",        "resourceType": "instance",        "resourceId": "string",        "assignedAt": "2019-08-24T14:15:22Z"      }    ],    "assignment": {      "id": "string",      "resourceType": "instance",      "resourceId": "string",      "assignedAt": "2019-08-24T14:15:22Z"    }  }}