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 a project to another subscription of the same tenant
Moves the project to targetSubscriptionId. SYNCHRONOUS: nothing in OpenStack
changes (the project keeps its id, Keystone project, app-cred, scope projection and every
resource); the catalog + billing rewrite is one transaction that either happens completely
or not at all. Billing is sealed under the SOURCE at cutoverAt; every usage hour starting
before billingBoundary belongs to the source, every hour starting at or after it to the
destination. An iam.project.move Operation is recorded already SUCCEEDED for the audit
trail (operationId); there is nothing to poll.
Authorization: a SUBSCRIPTION-level owner grant on BOTH the source and the destination
subscription: unreached project or destination 404, not owner on either end 403.
An API token is refused 403 TOKEN_SCOPE_MISSING (iam:write is never grantable); tenant
on non-payment hold 403 TENANT_SUSPENDED.
Validation / preconditions (checked before anything is written): destination equal to
the current subscription 422; different currency 409 CONFLICT; the project's region is not
the destination's defaultRegion 409 CONFLICT; destination at its project cap 409
QUOTA_EXCEEDED; the source would be left with no project 409 CONFLICT; unknown body
field 422.
Errors: 401; 403; 404; 409; 422; 500.
Idempotency/Concurrency: Idempotency-Key (UUID) is optional (recommended); a replay
returns the FIRST
move's cut-over instant instead of re-sealing billing. A refused move leaves no idempotency
record.
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.
tenantId*stringThe tenant id.
subscriptionId*stringThe subscription id (unique platform-wide, derived from the tenant id + the subscription's name at creation).
projectId*stringThe project id (also the project's scopeId).
Idempotency-Key?stringOptional; 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.
uuidapplication/json- body
Body of the project move.
targetSubscriptionId*stringThe destination subscription, in the same tenant.
The move, completed.
application/json- response
The 200 body of a project move.
projectId*stringfromSubscriptionId*stringtoSubscriptionId*stringcutoverAt*stringThe instant the project's billing was sealed under the source subscription.
date-timebillingBoundary*stringUsage hours starting before this instant belong to the source; at or after it, to the destination.
date-timeoperationId*stringThe already-SUCCEEDED iam.project.move Operation (audit trail; nothing to poll).
curl -X POST "https://example.com/tenants/string/subscriptions/string/projects/string/actions/move" \ -H "Content-Type: application/json" \ -d '{ "targetSubscriptionId": "string" }'{ "projectId": "string", "fromSubscriptionId": "string", "toSubscriptionId": "string", "cutoverAt": "2019-08-24T14:15:22Z", "billingBoundary": "2019-08-24T14:15:22Z", "operationId": "string"}