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.
Move one seat of an entitlement between two resources, atomically
Moves ONE seat from fromResourceId to toResourceId in a single transaction. There is never a
window in which the seat is on both resources or on neither.
A DEDICATED operation rather than "release then assign": two calls cannot transfer a seat on a FULL
pool at all — assigning first finds no free seat, and releasing first opens a window another caller
can steal the seat in. The transfer therefore succeeds even when every seat is taken, which is the
common case for a seat-based licence.
Validation: resourceType must be one of instance|volume|load_balancer; fromResourceId must
currently hold a seat of this entitlement (else 404 NOT_FOUND); toResourceId must be a LIVE
resource of the caller's own tenant (else 404) that does not already hold a seat of this entitlement
(else 409 CONFLICT); source and destination must differ (else 422 on field toResourceId); the
entitlement's term must not have ended (else 409). Caller needs billing:write, else 403.
Async & state: Synchronous and atomic under a row lock on the entitlement.
Errors: 401; 403; 404 unknown scope, entitlement, source assignment or destination resource; 409
destination already assigned / term ended; 422 malformed body or same source and destination; 500.
Idempotency/Concurrency: Replaying a completed transfer is a 404 (the source no longer holds the
seat), not a double move.
bearerTokenAuthorizationBearer <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.
scopeId*stringOpaque ownership+authorization scope resolving to tenant + subscription + project.
entitlementId*stringThe subscription-scoped entitlement's id.
application/json- body
resourceType*EntitlementResourceTypeThe kind of resource an entitlement seat can be applied to. Extensible — new kinds (a Kubernetes cluster) are added here without a data migration.
"instance""volume""load_balancer"fromResourceId*stringThe resource currently holding the seat.
toResourceId*stringThe resource to move the seat to. Must differ from fromResourceId.
The seat now sits on the destination resource.
application/json- 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/string/actions/transfer" \ -H "Content-Type: application/json" \ -d '{ "resourceType": "instance", "fromResourceId": "string", "toResourceId": "string" }'{ "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" } }}