Skip to content

Admin REST API

The admin server exposes a REST API over HTTPS (port 443 by default). All endpoints that modify state require a Bearer token in the Authorization header.

Every endpoint below is served at both its versioned path (/v1/status) and its bare path (/status); omitting the slug implies v1. The versioned form is canonical — use it in new integrations, since a future v2 will change what the bare path resolves to. The /deploy/ tree is exempt and is only ever served unversioned, because its URLs are baked into published install commands.

All /v1/configure/ endpoints require an account token. Volume-scoped endpoints (/v1/volumes/for-token/) accept a volume token. Meta-server endpoints (/v1/volumes/stats, /v1/volumes/retired, /v1/rate-bins) accept a meta store token.

Authorization: Bearer $TOKEN

Any JSON endpoint accepts pretty=true to indent the response (e.g. GET /v1/configure/volumes?pretty=true); the default is compact.

These endpoints provide generic CRUD operations on all admin resource tables. The {table} parameter corresponds to the API name of the resource (e.g., accounts, volumes, block-stores).

GET /v1/configure/{table}?key=value&...

Returns a JSON array of all records in the table. Query parameters are used as filters.

Response: 200 OK with JSON array.

GET /v1/configure/{table}/{id}
GET /v1/configure/{table}/{id1}/{id2}

Returns a single record by primary key. Composite-key resources (e.g., regions) use the two-ID form.

Response: 200 OK with JSON object.

POST /v1/configure/{table}
Content-Type: application/json
{ "field": "value", ... }

Creates a new record.

Response: 200 OK with the created JSON object.

PUT /v1/configure/{table}/{id}
PUT /v1/configure/{table}/{id1}/{id2}
Content-Type: application/json
{ "field": "new_value", ... }

Updates an existing record. Only provided fields are modified.

Response: 204 No Content.

DELETE /v1/configure/{table}/{id}
DELETE /v1/configure/{table}/{id1}/{id2}

Deletes a record. For volumes, this sets the retired_at timestamp rather than removing the row.

Response: 204 No Content.

TablePrimary KeyDescription
accountsidUser accounts
block-apiscodeBlock store API types (read-only)
block-storesidBlock store configurations
meta-storesidMetadata store registrations
providerscodeCloud providers
proxy-groupsidProxy groups
regionsprovider_code, codeProvider regions (composite key)
volumesidVolumes
volume-proxy-groupsvolume_id, proxy_group_idVolume-to-proxy-group associations
volume-tokenstokenVolume access tokens
GET /v1/volumes/for-token/settings
Authorization: Bearer $TOKEN

Returns the volume settings for the token’s associated volume, including block size, compression, encryption, retention, mount flags, and proxy group addresses.

PATCH /v1/volumes/for-token/secret-id
Authorization: Bearer $TOKEN
Content-Type: application/json
{ "secret_id": "xxxxxxxx" }

Registers or updates the encryption secret ID for the volume.

GET /v1/volumes/for-name/{volumeName}/tokens
Authorization: Bearer $TOKEN

Returns the list of volume tokens for the named volume.

PATCH /v1/volumes/for-name/{volumeName}/quota
Authorization: Bearer $TOKEN
Content-Type: application/json
{
"max_bytes": 3221225472,
"max_inodes": 0
}

Ensures a volume’s quotas are at least the given figures. Backs CSI volume expansion.

Volume creation (POST /v1/volumes) accepts the same two fields, where they set the initial quotas; 0 means unlimited there. In both cases the byte figure is converted using the volume’s block size, so the quota that ends up in force is the rounded-up block count reported back in the response.

FieldTypeDescription
max_bytesint64Storage quota in bytes, rounded up to a whole block when recorded. 0 leaves the storage quota unchanged.
max_inodesint64Inode quota. 0 leaves the inode quota unchanged.

Quotas only grow through this endpoint: it ensures a volume allows at least the figures given. A value the volume already satisfies leaves the quota unchanged and responds 200 with the figure in force, so a caller that is behind on the volume’s real size does not fail. To reduce a quota, set it directly with configure.flexfs update volume --maxBlocks/--maxInodes.

A volume with no quota in a dimension is refused with 400 for that dimension: there is no limit to raise, and the unlimited sentinel is not a figure a caller can meaningfully record as a capacity.

Responds 200 with the volume identity and the quota now in force:

{
"id": "992467d9-1f45-439d-86e1-2bbb253711c6",
"name": "pvc-76021e89-28ed-44d6-82be-34bc4e23a5bb",
"max_blocks": 768,
"max_bytes": 3221225472,
"max_inodes": 0
}

Returns 404 for an unknown or retired volume name, and 401 for a token that is not an account token.

DELETE /v1/volumes/for-name/{volumeName}
Authorization: Bearer $TOKEN

Retires a volume by name.

DELETE /v1/volumes/{volumeID}
Authorization: Bearer $TOKEN

Retires or cleans a volume by ID.

GET /deploy/install-mount.sh

Returns a shell script that downloads and configures the mount client. No authentication required.

GET /deploy/{channel}/{version}/linux/{arch}/mount.flexfs

Serves the mount client binary. Channels are staging and production. No authentication required.

POST /v1/volumes/stats
Authorization: Bearer $TOKEN
Content-Type: application/json

Accepts volume statistics from metadata servers for billing and metering.

GET /v1/volumes/retired
Authorization: Bearer $TOKEN

Returns the IDs of volumes that have been retired but not yet cleaned, for the authenticated metadata server. There is no time window — a volume appears here until its cleanup completes.

Response: 200 OK with a JSON array of volume-ID strings.

GET /v1/rate-bins
Authorization: Bearer $TOKEN

Proxies rate bin data from the stat server. Returns a JSON object mapping size bin numbers (0-74) to per-GiB monthly dollar rates ($/GiB/month). Used by metadata servers to compute the cost field in analyze.flexfs and find.flexfs. See Cost and Rate Bin in the glossary.

GET /v1/status

Returns server health status. No authentication required.