Previous Release: 2.1 Release New Release: 2.2
This document covers API changes that affect customers with existing integrations for billing and GPUaaS instance creation. Please review all sections marked BREAKING carefully and update your integrations before upgrading.
Table of Contents
1. Breaking Changes Summary
The following changes require updates to existing API integrations:
Change | Impact | Action Required |
|---|---|---|
Instance creation request body restructured | All instance creation calls will fail | Update request payloads to new format |
GPUaaS pod creation moved from subscription to instance API |
| Use |
GPUaaS pod costs move to team/workspace billing |
| Use team/workspace billing with |
Billing Swagger documentation corrected | Swagger/OpenAPI spec consumers may need updates | See note — actual API behavior unchanged |
Billing response format changed | Billing parsers will break | Update response parsing (PCI devices moved per-instance, new metadata fields) |
Instance credentials response changed | Credential parsing may break | Handle nullable fields, new |
| Service detail calls will return 404 | Use |
| Worker connection parsing may break | Handle nullable |
New resource fields use float types | Clients using old integer-typed resource structs | Use new float-typed response fields |
Rate limiting added (60 req/min) | High-frequency clients may get 429 errors | Implement rate limit handling and backoff |
| Ray head port calls will fail | Remove calls to this endpoint |
2. Instance Creation API Changes
BREAKING: New Request Body Format
The instance creation endpoint POST /service/i/create-instance now uses a unified request body that supports both VM and Pod instance types.
Old Request Format:
{ "service_id": "uuid", "name": "my-instance", "description": "string", "workspace_id": "string", "team_id": "uuid", "region_id": 1, "cluster_id": 1, "image_id": 1, "instance_type_id": "string", "root_storage_type_id": "string", "additional_disk_one_type_id": "string", "additional_disk_two_type_id": "string", "networks": [1, 2], "public_keys": ["ssh-rsa ..."], "pool_ids": [1], "pcidev_ids": [1], "gpu_card_count": 1, "gpu_model": "string", "recipe_id": 1 }
New Request Format:
{ "service_id": "uuid", "name": "my-instance", "description": "string", "workspace_id": "uuid", "team_id": "uuid", "region_id": 1, "image_hash": "string", "instance_type_id": "uuid", "root_storage_type_id": "uuid", "public_keys": ["ssh-rsa ..."], "vm_opts": { "additional_disk_one_type_id": "string", "additional_disk_two_type_id": "string", "networks": [1, 2], "passthrough_accelerators": "string", "gpu_card_count": 1 }, "pod_opts": { "pool_id": 1, "vgpus": 4, "shared_volumes": [1, 2] } }
Key field changes:
Field | Old | New | Notes |
|---|---|---|---|
| uuid (optional, pointer) | uuid (required, value) | Now required — must always be provided |
| integer | Removed | Replaced by |
| N/A | string | New field — images are now referenced by hash |
| integer | Removed | No longer needed; region is derived from cluster |
| int | uint | Type changed from signed to unsigned integer |
| string | uuid | Type changed |
| string | *uuid (optional) | Type changed to nullable UUID pointer — omit or set null if not applicable |
| string | *uuid (optional) | Type changed to nullable UUID pointer — omit or set null if not applicable |
| integer array | Removed | Replaced by |
| integer array | Removed | Removed entirely — no direct replacement |
| string | Removed | Replaced by |
| integer (optional) | Removed | Managed internally — no longer a client-supplied field |
| N/A | object (optional) | New — VM-specific options grouped here |
| N/A | object (optional) | New — Pod/GPUaaS-specific options grouped here |
Important: For VM services, provide vm_opts. For Pod/GPUaaS services (service type pod_accelerator), provide pod_opts. Providing the wrong options object for the service type will return an error.
New Instance Response Fields
Instance responses now include:
Field | Type | Description |
|---|---|---|
| enum: | Whether the instance is a VM or a Pod |
| string array | Public IP addresses assigned to the instance |
3. GPUaaS Pod Creation: Subscription to Instance Migration
BREAKING: Pods Are Now Created as Instances, Not Subscriptions
In the previous release, GPUaaS pods were created by subscribing to a GPU pool via a dedicated endpoint. In Titan, GPUaaS pods are now first-class instances created through the same unified instance creation endpoint as VMs.
Old Approach (Oct Release): Pool Subscription
Endpoint: POST /gpuaas/pool/subscribe
Request body (SubscribeToPoolPayload):
{ "pool_id": 1, "team_id": "uuid", "is_vip_priority": false, "vgpus": 4, "guaranteed_gpu_share_percent": 100, "instance_type_id": "uuid", "ephemeral_storage_block_id": "uuid", "shared_volumes": [1, 2], "image_uuid": "uuid", "port_guid": "string (optional)", "ifb_subscription_id": "string (optional)" }
This created a PoolSubscription record, and a pod was provisioned asynchronously as a side effect of the subscription. The pod did not appear in the instances list and was managed entirely through the GPUaaS subscription system.
New Approach (Titan): Unified Instance Creation
Endpoint: POST /service/i/create-instance
Request body (same endpoint as VM creation, using pod_opts):
{ "service_id": "uuid (must be a pod_accelerator service)", "name": "my-pod", "description": "string", "workspace_id": "uuid", "team_id": "uuid", "region_id": 1, "image_hash": "string", "instance_type_id": "uuid", "root_storage_type_id": "uuid", "public_keys": ["ssh-rsa ..."], "pod_opts": { "pool_id": 1, "vgpus": 4, "shared_volumes": [1, 2] } }
The backend detects the pod_accelerator service type and provisions a pod directly. The pod is created as an Instance record with nature: "pod" and appears in the unified instances list alongside VMs.
Field Mapping: Old Subscription to New Instance Creation
Old Field ( | New Location | Notes |
|---|---|---|
|
| Same concept, nested under |
|
| Moved to top-level shared field |
|
| Same concept, nested under |
|
| Moved to top-level shared field |
|
| Renamed — same concept |
|
| Same concept, nested under |
|
| Renamed — images now referenced by hash string |
| Removed | No longer a user-supplied option |
| Removed | No longer a user-supplied option |
| Removed | Infiniband handling is now managed internally |
| Removed | Infiniband handling is now managed internally |
N/A |
| New required field — must reference a |
N/A |
| New required field — human-readable instance name |
N/A |
| New required field — instances belong to a workspace |
N/A |
| New required field — explicit region selection |
N/A |
| New optional field — SSH public keys for pod access |
Key Behavioral Differences
Aspect | Old (Subscription) | New (Instance) |
|---|---|---|
Conceptual model | "Subscribe to a GPU pool" — pod is a side effect | "Create an instance" — pod is a first-class resource |
Visibility | Pod did not appear in instance listings | Pod appears in |
Billing | Only via | Appears in team/workspace billing with |
Lifecycle management | Managed via subscribe/unsubscribe endpoints | Managed via unified instance endpoints (resize, deprovision, volume actions) |
GPU allocation | Implicit during provisioning | Explicit pre-reservation via HaiDra before provisioning; auto-cleanup on failure |
Service selection | No service concept — user directly subscribed to a pool | Must select a |
Workspace assignment | Pods had no workspace | Pods belong to a workspace (required for billing and access control) |
Unsubscribe Replaced by Instance Deletion
Old: POST /gpuaas/pool/unsubscribe with a subscription ID.
New: Delete or deprovision the instance through the unified instance management endpoints. The pod deprovisioning flow handles GPU release and cleanup automatically.
4. Billing API Changes
Swagger Documentation Correction: timezone and region_id Parameters
Note: The previous Swagger/OpenAPI specification incorrectly documented timezone and region_id as required path parameters. In practice, the actual API has always accepted these as optional query parameters. The Titan release corrects the Swagger documentation to match the actual behavior.
If you are calling the API directly, no changes are needed — the endpoint URLs and parameter handling are unchanged.
If you generated client code from the Swagger spec, you may need to regenerate your client, as the spec now correctly reflects these as optional query parameters rather than required path segments.
The billing endpoint URLs remain:
Endpoint | URL | Query Parameters |
|---|---|---|
Team billing |
|
|
Shared storage billing |
|
|
GPUaaS pool billing |
|
|
Workspace billing |
|
|
Team billing by workspace |
|
|
BREAKING: Billing Estimate Request
The billing estimate endpoint POST /calculate-instance-billing-estimate now accepts the same new UnifiedInstanceCreateOpts body described in Section 2.
BREAKING: GPUaaS Pod Costs Move to Team/Workspace Billing
In the previous release, GPUaaS pod costs were only visible through the dedicated GPUaaS pool billing endpoint (/team-billing/gpuaas-pool/). In Titan, legacy GPUaaS pods are migrated to unified instances with nature: "pod", and their costs (GPU, vRAM, TFlops, Subscription Rate, Ephemeral Storage, CPU, RAM) now appear in the standard team and workspace billing responses alongside VM instance costs.
Important: Historical billing data moves with the migration. When a legacy GPUaaS pod is migrated to a unified instance:
The new instance preserves the original creation timestamp of the pool subscription, so historical billing queries (e.g., for periods months before the upgrade) will return the migrated pod as an instance with
nature: "pod".The original
pool_subscriptionsrow is permanently deleted from the database during migration. This means the dedicated GPUaaS pool billing endpoint (/team-billing/gpuaas-pool/) will no longer return data for migrated subscriptions — including historical periods.There is no double-counting: costs appear exclusively in the team/workspace billing view after migration.
If you rely on the /team-billing/gpuaas-pool/ endpoint:
After upgrade, this endpoint will return empty or reduced results as migrated subscriptions are removed from the underlying data.
To retrieve GPUaaS pod costs, use the standard team or workspace billing endpoints and filter by
nature: "pod".The
/team-billing/gpuaas-pool/endpoint remains functional for any non-migrated pool subscriptions, but all legacy pods are migrated during the upgrade process.
BREAKING: Billing Response Format Changes
PCI device costs consolidated per-instance:
The top-level
pci_deviceskey has been removed from team and workspace billing responses.PCI device costs are now included within each instance's billing data under a
pci_devkey.
New per-instance metadata fields in billing responses:
Team and workspace billing responses now include both VM and Pod instances. Each instance entry includes new metadata fields:
Field | Type | Description |
|---|---|---|
| string | Human-readable instance name |
| enum: | Whether this is a VM or Pod instance |
| string (optional) | GPU model type (pod instances only) |
| integer (optional) | GPUaaS pool ID (pod instances only) |
| string (optional) | GPUaaS pool name (pod instances only) |
| uint (optional) | GPU sharing ratio (pod instances only) |
| string (optional) | GPU vendor type (pod instances only) |
| object (optional) | Instance type details including ephemeral storage (pod instances only) |
| decimal (optional) | Total cost for the billing period (pod instances only) |
Pod instance billing resources: For instances with nature: "pod", the Resources map contains pod-specific cost categories: Subscription Rate, GPU, vRAM, CPU, RAM, Ephemeral Storage, and TFlops — rather than the VM-style resources (Disk, IP, etc.).
Usage data structure changes:
statsandsymbolfields are now omitted when emptyNew fields:
quantity(float64) andtotal_usage(float64)Resourcesfield type changed frommap[string]decimaltomap[string]interface{}(can contain richer nested data including theUsagestruct)
New Endpoint: Instance-Level Billing
Method | Endpoint | Description |
|---|---|---|
|
| Billing data for a specific instance |
Optional query param: timezone (enum: local, utc).
5. GPUaaS & Pod Management Changes
BREAKING: Pool Worker Connection Details Schema Change
The PoolWorkersConnectionDetails response has changed significantly:
Field | Old Type | New Type | Notes |
|---|---|---|---|
| uint (required) | uint (nullable) | Now nullable |
| string (required) | string (nullable) | Now nullable |
| string (required) | string (nullable) | Now nullable |
| int (required) | int (nullable) | Now nullable |
| string (required) | string (nullable) | Now nullable |
| N/A | uint (required) | New field |
| N/A | string (required) | New field |
| N/A | string (nullable) | New field |
| N/A | uint (required) | New field |
| N/A | uint (nullable) | New field |
Available Resources: New Float-Typed Fields
The GET /gpuaas/pool/{pool_id}/available_resources endpoint is new in this release and uses float64 for CPU, memory, and storage fields. The related MaxDeployableVGpusPerNode response now includes new float32 fields (available_cpu_cores, available_memory_mb, available_storage_mb) alongside the existing integer vgpu_count. If you previously used the internal AllocatableResourcesNode struct (which had integer types for resource fields), note that the new response structs use float types instead.
BREAKING: Subscribed Teams Response Change
GET /gpuaas/pool/{pool_id}/subscribed_teams now:
Includes
pool_subscription_idin each entryThe
statusfield now always returns"subscribed"(previously returned the actual pool subscription status)
New Pod Lifecycle Endpoints
Method | Endpoint | Description |
|---|---|---|
|
| List all running pods (optional |
|
| Provision a new pod |
|
| Deprovision a pod |
|
| Resize a pod (returns recipe execution UUID) |
|
| Attach/detach a volume to/from a pod |
|
| Get pod volume mount info |
|
| Extract detailed pod info |
|
| Get pod status |
|
| Migrate legacy pods |
New Pod Management Endpoints (User Panel)
Method | Endpoint | Description |
|---|---|---|
|
| Mount/unmount volumes on pods |
|
| Resource usage metrics for a pod |
|
| Resize pod instance type |
|
| Resize pod ephemeral storage |
|
| Get available resize instance types |
|
| Get available resize storage options |
|
| Cost estimate for resize |
New GPUaaS Resource Endpoints
Method | Endpoint | Description |
|---|---|---|
|
| Available CPU, memory, storage per node |
|
| Batch query max deployable vGPUs across pools |
|
| Reboot a GPUaaS node |
New Service Type: pod_accelerator
A new service type pod_accelerator has been added. API clients that parse service type enums must now handle this value in addition to the existing types (cpu_only, cpu_gpu_card, cpu_gpuaas).
GPU Subscription Flow Change
The pool subscription flow now pre-reserves GPUs before provisioning. On recipe failure, GPU assignments are automatically cleaned up. On success, assignments are confirmed. This is transparent to API clients but may affect timing expectations.
GPU Spec Listing Change
GET /gpuaas/cards-specs/all no longer requires the timestamp query parameter. The parameter is ignored if sent. The endpoint now always returns all GPU specs.
6. New Endpoints
Unified Instance Management
Method | Endpoint | Description |
|---|---|---|
|
| Paginated listing of all instances (VMs + Pods) |
|
| Detailed info for a single unified instance |
|
| List exposed services for a pod instance |
|
| Retry provisioning a failed VM |
|
| Force-refresh pod connection details |
Service Provisioning Flow
Method | Endpoint | Description |
|---|---|---|
|
| Scenarios accessible to a team |
|
| All regions accessible to a team |
|
| Services under a scenario for a team |
|
| Replaces removed |
|
| Compatible storage blocks for a service |
|
| Compatible shared volumes (pod services) |
|
| Compatible additional disks for VM services |
|
| Diagnostic info about service eligibility |
Service Options
Method | Endpoint | Description |
|---|---|---|
|
| Image options filtered by service |
|
| Instance type options by service |
|
| Storage block options by service |
|
| Accelerators grouped by vendor |
|
| Accelerator pool options for a service |
Instance IP Retrieval
Method | Endpoint | Description |
|---|---|---|
|
| Get IPs for instances updated since a timestamp |
|
| Get public IPs for a specific instance |
Recipe Execution
Method | Endpoint | Description |
|---|---|---|
|
| Get recipe execution status by UUID |
7. Removed Endpoints
Method | Endpoint | Replacement |
|---|---|---|
|
| Use |
|
| Removed (no replacement) |
|
| Removed (was already returning 403) |
|
| Removed |
8. Instance Credentials Response Change
BREAKING
The instance credentials response now includes additional fields and makes all fields nullable:
Old format:
{ "username": "string", "password": "string" }
New format:
{ "ip": "string or null", "username": "string or null", "password": "string or null", "port": 22 }
9. Rate Limiting
A new rate limiting system has been added to all authenticated API endpoints.
Parameter | Value |
|---|---|
Default limit | 60 requests per minute |
Burst allowance | 10 requests |
Response code when exceeded | HTTP 429 Too Many Requests |
Exemption | Full administrator accounts |
Action required: Implement retry logic with exponential backoff for HTTP 429 responses in your API clients.
10. New Error Codes
Instance Creation Errors
Error Code | Description |
|---|---|
| VM options provided for a pod_accelerator service |
| Pod options provided for a VM service |
| Missing pod_opts for pod_accelerator service |
| Missing vm_opts for GPU VM service |
| Invalid GPU card count requested |
| GPU count exceeds maximum allowed |
| No GPU pools available for the service |
| General instance creation failure |
| No images compatible with the selected service |
Pod Operation Errors
Error Code | Description |
|---|---|
| Pod provisioning failed |
| Pod volume attach failed |
| Pod volume detach failed |
| Pod deprovisioning failed |
| Pod resizing failed |
| Failed to provision pod |
| Failed to deprovision pod |
| Volume action failed |
| Resize failed |
Billing & Service Errors
Error Code | Description |
|---|---|
| Rate limit exceeded (HTTP 429) |
| Team has no accessible regions |
| GPUaaS not active in the selected region |
| Service is not a GPU service |
| Service is not a pod_accelerator |
11. Migration Guide
Step 1: Migrate GPUaaS Pod Creation from Subscription to Instance API
If you create GPUaaS pods via POST /gpuaas/pool/subscribe:
Switch to
POST /service/i/create-instancewith apod_acceleratorservice.Map your existing fields to the new format (see Section 3 for full field mapping):
pool_id->pod_opts.pool_idvgpus->pod_opts.vgpusshared_volumes->pod_opts.shared_volumesinstance_type_id-> top-levelinstance_type_idephemeral_storage_block_id->root_storage_type_idimage_uuid->image_hashteam_id-> top-levelteam_id
Add new required fields:
service_id(apod_acceleratorservice),name,workspace_id,region_id.Remove fields that no longer exist:
is_vip_priority,guaranteed_gpu_share_percent,port_guid,ifb_subscription_id.Replace
POST /gpuaas/pool/unsubscribewith instance deletion/deprovisioning through the unified instance endpoints.
Step 2: Update VM Instance Creation Calls
service_idis now required (previously optional) — always provide it.Replace
image_id(integer) withimage_hash(string).Remove
cluster_idfrom requests.Change
workspace_idto UUID format. Changeinstance_type_idandroot_storage_type_idto UUID format (these are now nullable — omit or set null when not applicable).Move VM-specific fields (
additional_disk_*,networks,gpu_card_count) into avm_optsobject. Note:gpu_modelis nowvm_opts.passthrough_accelerators.Remove
pcidev_idsandrecipe_id— these fields no longer exist.
Step 3: Update Billing Response Parsing
Note: The billing endpoint URLs are unchanged. The timezone and region_id parameters were always optional query parameters in practice — the previous Swagger spec was incorrect and has now been corrected. If you generated client code from the old Swagger spec, regenerate it.
Update billing response parsers:
Remove top-level
pci_devicesparsing; PCI costs are now within each instance entry under apci_devkey.Handle new per-instance metadata fields (
instance_name,nature,model_type,pool_id,pool_name,total_cost).Update
Resourcesparsing to handlemap[string]interface{}instead ofmap[string]decimal.
Team/workspace billing now includes pod instances (migrated GPUaaS pods) alongside VMs. Filter by
naturefield ("vm"or"pod") if you need to separate them. Pod instances have different resource categories (e.g.,Subscription Rate,GPU,TFlops) than VMs.If you use
/team-billing/gpuaas-pool/: After upgrade, migrated pool subscriptions are permanently removed from the database, so this endpoint will return empty or reduced results. Switch to the team/workspace billing endpoints and filter bynature: "pod"to retrieve GPUaaS pod costs. Historical billing data for all periods (including pre-upgrade) is available through the team/workspace billing path.
Step 4: Update Billing Estimate Calls
Update POST /calculate-instance-billing-estimate to use the same new UnifiedInstanceCreateOpts request body format.
Step 5: Handle Nullable Fields in Worker Connection Details
If you parse PoolWorkersConnectionDetails, update your code to handle:
username,password,port,ipas nullable (may benull)New required fields:
region_id,team_id,pool_id
Step 6: Update Instance Credentials Parsing
Handle ip, username, password as nullable strings and add handling for the new port field.
Step 7: Replace Removed Endpoints
Replace
/service/i/detailswith/service/i/provisioning-info.Remove any calls to
/gpuaas/sub/{sub_id}/pool/{pool_id}/target-url.
Step 8: Handle Available Resources Response Types
The GET /gpuaas/pool/{pool_id}/available_resources endpoint is new and returns float64 for CPU, memory, and storage fields. The MaxDeployableVGpusPerNode response also now includes new float32 resource fields. Ensure your client models use float types for these fields.
Step 9: Implement Rate Limit Handling
Add retry logic with exponential backoff for HTTP 429 responses. The default limit is 60 requests per minute with a burst of 10.
Step 10: Handle New Service Type
Update service type parsing to handle the new pod_accelerator enum value in addition to cpu_only, cpu_gpu_card, and cpu_gpuaas.
For the complete Swagger/OpenAPI specification, refer to the updated swagger.json and swagger.yaml files included in this release.