Storage Endpoints

Endpoints are under /v1/resource/volumes and require authentication.

Base URL: https://api.gpcn.com/v1

See the API Reference → for examples in TypeScript, Python, Go, and C#.

List Volumes

GET /resource/volumes

Returns a paginated list of volumes.

Query Parameters

Parameter Type Default Description
page integer 1 Page number
limit integer 10 Items per page (max 100)
sort string createdAt:desc Sort field and direction
search string — Search by name
filter[virtualMachineId] UUID — Filter by attached VM
filter[status] string — Filter by status
filter[resourceGroupId] UUID — Filter by resource group
filter[regionId] integer — Filter by region
filter[datacenterId] UUID — Filter by data center
filter[volumeTypeId] integer — Filter by volume type
filter[volumeSizeId] integer — Filter by volume size
filter[sizeGb] integer — Filter by exact size in GB

Response

Paginated array of volume objects with data center, VM attachment, and resource group info.

curl https://api.gpcn.com/v1/resource/volumes \
  -H "X-API-Key: gpcn_your_api_key_here"

Create Volume

POST /resource/volumes

Provision a new block storage volume.

Request Body

{
  "name": "data-disk-1",
  "datacenterId": "dc-uuid",
  "volumeTypeId": 1,
  "volumeSizeId": 11,
  "sizeGb": 100,
  "resourceGroupId": "880e8400-e29b-41d4-a716-446655440001"
}
Field Type Required Description
name string Yes Unique volume name
datacenterId UUID Yes Target data center
volumeTypeId integer Yes Volume type ID
volumeSizeId integer Yes Volume size ID
sizeGb integer Yes Size in GB
resourceGroupId UUID No Resource group to create into. Omitted: the volume is placed in the tenant's Default resource group.
curl -X POST https://api.gpcn.com/v1/resource/volumes \
  -H "X-API-Key: gpcn_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "data-disk-1",
    "datacenterId": "dc-uuid",
    "volumeTypeId": 1,
    "volumeSizeId": 11,
    "sizeGb": 100,
    "resourceGroupId": "880e8400-e29b-41d4-a716-446655440001"
  }'

Response (202 Accepted)

Job tracking object.

Error: 409 Conflict

Volume name already exists.

Get Volume Details

GET /resource/volumes/{id}

Response

Full volume object with status, attachment info, size, type, and data center.

Move Volume

PUT /resource/volumes/{id}

Moves a volume into another resource group. This is the only change this endpoint accepts — it doesn't rename the volume. The change takes effect immediately; there's no job to poll, and the response carries the volume's updated details.

Requires volume:update in the group the volume is in now and in the destination group.

Request Body

{ "resourceGroupId": "880e8400-e29b-41d4-a716-446655440002" }
Field Type Required Description
resourceGroupId UUID Yes The resource group to move the volume into. null is refused (422) — every volume belongs to a group, so to take one out of a group, move it into your tenant's Default resource group instead.
curl -X PUT https://api.gpcn.com/v1/resource/volumes/vol-uuid \
  -H "X-API-Key: gpcn_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{ "resourceGroupId": "880e8400-e29b-41d4-a716-446655440002" }'

Response (200 OK)

Error: 403 Forbidden

You don't hold volume:update in the volume's current group or in the destination group (code Insufficient Permissions), or the destination isn't a resource group you're a member of (code Entity Access Denied, message "You do not have access to the specified resource group"). A resourceGroupId that names no group in your tenant answers one of these two 403s, never a 404.

Error: 404 Not Found

No volume with this id exists in your tenant, or it's in a resource group you're not a member of — both cases answer the same "Volume not found".

Delete Volume

DELETE /resource/volumes/{id}

Volume must be in Available state (not attached).

Response (202 Accepted)

Job tracking object.

Attach Volume to VM

PUT /resource/volumes/{id}/attach

Request Body

{ "virtualMachineId": "vm-uuid" }

VM must be in the same data center. VM must be below its maximum volume attachment count.

Response (202 Accepted)

Detach Volume from VM

PUT /resource/volumes/{id}/detach

Response (202 Accepted)

Resize Volume

PUT /resource/volumes/{id}/resize

Expand the volume to a larger size. Cannot shrink.

Request Body

{
  "newSizeGb": 200,
  "newVolumeSizeId": 13
}
Field Type Required Description
newSizeGb integer Yes New size in GB (must be larger)
newVolumeSizeId integer No New volume size ID

Response (202 Accepted)

List Attachable VMs

GET /resource/volumes/{id}/available-virtual-machines

List VMs in the same data center that this volume can be attached to.

Response

Array of VM objects with current and maximum volume counts.

Bulk Delete

POST /resource/volumes/bulk/delete

Request Body

{ "ids": ["vol-uuid-1", "vol-uuid-2"] }

1–50 IDs. Returns array of job tracking objects.

Bulk Detach

POST /resource/volumes/bulk/detach

Request Body

{ "ids": ["vol-uuid-1", "vol-uuid-2"] }

1–50 IDs. Returns array of job tracking objects.

Volume Sizes by Data Center

GET /resource/data-centers/{id}/volume-sizes

Returns available volume types and sizes for a data center.

Response

{
  "success": true,
  "data": {
    "datacenterId": "dc-uuid",
    "volumeTypes": [
      {
        "id": 1,
        "name": "SSD",
        "description": null,
        "availableSizes": [
          {
            "id": 10,
            "sizeGb": 50,
            "displayName": "50 GB",
            "maxVolumesPerVm": 8
          }
        ]
      }
    ]
  }
}

Workflow: Create a Volume and Attach to a VM

Volume creation is asynchronous. Here's the complete pattern — create, wait, then attach:

# 1. Check available sizes for your data center
curl -s https://api.gpcn.com/v1/resource/data-centers/dc-uuid/volume-sizes \
  -H "X-API-Key: gpcn_your_api_key_here" | jq '.data.volumeTypes'

# 2. Create the volume
RESPONSE=$(curl -s -X POST https://api.gpcn.com/v1/resource/volumes \
  -H "X-API-Key: gpcn_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{"name": "data-disk-1", "datacenterId": "dc-uuid", "volumeTypeId": 1, "volumeSizeId": 11, "sizeGb": 100}')

JOB_ID=$(echo $RESPONSE | jq -r '.data.jobId')
VOL_ID=$(echo $RESPONSE | jq -r '.data.id')

# 3. Wait for creation to complete — see Async Operations for the full polling pattern

# 4. Attach to a VM
curl -X PUT "https://api.gpcn.com/v1/resource/volumes/$VOL_ID/attach" \
  -H "X-API-Key: gpcn_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{"virtualMachineId": "vm-uuid"}'

For the full polling pattern, see Async Operations.

Next Steps