Account Management API
Account profile, subscription, plan discovery, email-change workflow, and quota administration.
Authentication Required: All protected endpoints on this page require X-API-Key. Most account-level mutations require an account root user.
User profile and user CRUD already have a dedicated page at /api/users. This page covers the remaining /v1/user-management/* account-level endpoints.
Account and Subscription Endpoints
Update Account
PUT /v1/user-management/account
Root users only.
Request body:
{
"display_name": "Platform Team",
"description": "Shared ScaleBox account"
}Get Active Subscription
GET /v1/user-management/account/subscription
Returns data.subscription, which is the active AccountSubscription record including its nested plan.
Change Subscription Plan
POST /v1/user-management/account/subscription
Root users only.
Request body:
{
"plan_name": "pro"
}If the account has neither balance nor a verified payment method, the API returns 402 Payment Required.
List Subscription Change History
GET /v1/user-management/account/subscription/history
Root users only.
Query parameters:
| Name | Type | Required | Description |
|---|---|---|---|
| page | integer | No | Page number, default 1. |
| limit | integer | No | Page size, default 50. |
| page_size | integer | No | Alias for limit. |
Response:
{
"success": true,
"data": {
"history": [
{
"change_id": "chg-1234567890ab",
"account_id": "acc-123456789",
"subscription_id": "sub-1234567890ab",
"old_plan_name": "hobby",
"new_plan_name": "pro",
"change_reason": "user_upgrade",
"old_period_start": "2026-03-01T00:00:00Z",
"old_period_end": "2026-03-31T00:00:00Z",
"new_period_start": "2026-04-01T00:00:00Z",
"new_period_end": "2026-04-30T00:00:00Z",
"prorated_refund_amount": 0,
"old_plan_price": 0,
"new_plan_price": 20,
"invoice_id": "inv-1234567890ab",
"changed_at": "2026-04-01T00:00:00Z"
}
],
"pagination": {
"page": 1,
"limit": 50,
"total": 1,
"total_pages": 1,
"offset": 0
}
},
"timestamp": "2026-04-20T12:34:56Z"
}List Public Plans
GET /v1/user-management/plans
Returns data.plans, where each plan includes fields such as:
plan_name,display_name,descriptionprice_amount,currency,billing_interval,is_freemax_concurrent_sandboxes,max_cpu_cores_per_sandbox,max_memory_gb_per_sandbox,max_storage_gb_per_sandbox,max_sandbox_timeout_seconds,persistence_days
Account Email Change Workflow
Protected endpoints:
POST /v1/user-management/account/email-change-requestGET /v1/user-management/account/email-change-statusPOST /v1/user-management/account/clear-email-change-requests
Public confirmation endpoint:
POST /v1/user-management/account/confirm-email-change
Request Account Email Change
Root users only.
{
"current_email": "owner@example.com",
"new_email": "billing@example.com"
}The backend sends confirmation links to both addresses and rate-limits new requests for 30 minutes.
Check Email Change Status
GET /v1/user-management/account/email-change-status
Possible response states include:
has_pending_request: falsestatus: "none_confirmed"status: "partial_confirmed"status: "both_confirmed"
Confirm Email Change
POST /v1/user-management/account/confirm-email-change
Public endpoint.
{
"token": "uuid-token-from-email"
}When only one side has confirmed, the API returns status: "pending" plus pending_email. After both confirmations, it returns status: "completed" and updates the account email for all users in the account.
User Quota Administration
Root users can manage per-user allocations with:
GET /v1/user-management/quota-allocationsPOST /v1/user-management/quota-allocationsPUT /v1/user-management/quota-allocations/{allocation_id}DELETE /v1/user-management/quota-allocations/{allocation_id}POST /v1/user-management/quota-allocations/{allocation_id}/revoke
Quota fields:
cpu_seconds_monthlyram_gb_secondssandbox_storage_gb_secondstraffic_gb_secondstemplate_storage_gbconcurrent_sandboxes
List Quota Allocations
GET /v1/user-management/quota-allocations
Query parameters:
| Name | Type | Required | Description |
|---|---|---|---|
| include_inactive | boolean | No | Include inactive allocations. |
| page | integer | No | Page number. |
| limit | integer | No | Page size. |
| page_size | integer | No | Alias for limit. |
Response:
{
"success": true,
"data": {
"allocations": [
{
"allocation_id": "qal-1234567890ab",
"account_id": "acc-123456789",
"user_id": "usr-1234567890ab",
"allocated_by_user_id": "usr-root123456",
"cpu_seconds_monthly": 500000,
"ram_gb_seconds": 1200000,
"sandbox_storage_gb_seconds": 2400000,
"traffic_gb_seconds": 50000,
"template_storage_gb": 50,
"concurrent_sandboxes": 3,
"status": "active",
"created_at": "2026-04-01T00:00:00Z",
"updated_at": "2026-04-15T08:00:00Z"
}
],
"pagination": {
"page": 1,
"limit": 50,
"total": 1,
"total_pages": 1,
"offset": 0
}
},
"timestamp": "2026-04-20T12:34:56Z"
}Review Team Quota Requests
GET /v1/user-management/quota-requests
List query parameters:
| Name | Type | Required | Description |
|---|---|---|---|
| status | string | No | Filter by pending, approved, or denied. |
| page | integer | No | Page number. |
| limit | integer | No | Page size. |
| page_size | integer | No | Alias for limit. |
Response shape:
{
"success": true,
"data": {
"requests": [],
"pagination": {
"page": 1,
"limit": 50,
"total": 0,
"total_pages": 0,
"offset": 0
}
},
"timestamp": "2026-04-20T12:34:56Z"
}Review endpoint:
POST /v1/user-management/quota-requests/{request_id}/review
{
"action": "approve",
"review_notes": "Approved for CI expansion"
}action must be approve or deny.
Common Errors
400: invalid body, duplicate pending request, or unsupported state transition402: subscription change requires a verified payment method or balance403: caller is not an account root user404: account object, quota allocation, or quota request not found409: subscription upgrade already in progress429: email-change request was made too recently