REST API Reference

The NodeFoundry API is a REST API served over HTTPS. All responses are JSON. Base URL: https://api.nodefoundry.io


Authentication

All requests must include an Authorization header with a Bearer token. Generate API keys from Settings → API Keys in the dashboard.

Authorization: Bearer nf_sk_live_xxxxxxxxxxxxxxxxxxxxxxxx
Key prefixScope
nf_sk_live_Live environment — full access
nf_sk_test_Sandbox environment — no real hardware
nf_sk_ro_Read-only — GET requests only

Rate limits: 300 req/min (Starter), 600 req/min (Professional), unlimited (Enterprise).


Clusters

GET /v1/clusters List all clusters

Returns all clusters ordered by creation date descending.

Query parameters

ParameterTypeDescription
pageintegerPage number. Default: 1.
per_pageintegerMax 100. Default: 25.
statusstringFilter: HEALTH_OK, HEALTH_WARN, HEALTH_ERR.
curl https://api.nodefoundry.io/v1/clusters 
  -H "Authorization: Bearer nf_sk_live_..."
{
  "data": [
    {
      "id": "clus_01hyfge4qpkx",
      "name": "prod-01",
      "status": "HEALTH_OK",
      "ceph_version": "reef",
      "node_count": 12,
      "osd_count": 96,
      "raw_capacity_tib": 847.2,
      "created_at": "2026-01-15T09:22:00Z"
    }
  ],
  "meta": { "page": 1, "per_page": 25, "total": 1 }
}
POST /v1/clusters Create a cluster

Provisions a new Ceph cluster from registered nodes. Returns immediately; poll /v1/operations/{id} for progress.

Request body

FieldTypeRequiredDescription
namestringYesLowercase alphanumeric and hyphens.
node_idsstring[]YesIDs of registered nodes. Minimum 3.
ceph_versionstringYes"reef" or "squid".
failure_domainstringNo"host" (default), "rack", or "zone".
replication_factorintegerNoDefault: 3.
curl -X POST https://api.nodefoundry.io/v1/clusters 
  -H "Authorization: Bearer nf_sk_live_..." 
  -H "Content-Type: application/json" 
  -d '{"name":"prod-01","node_ids":["node_01abc","node_01def","node_01ghi"],"ceph_version":"reef"}'
{
  "data": {
    "id": "clus_01hyfge4qpkx",
    "name": "prod-01",
    "status": "CREATING",
    "operation_id": "op_01jkl3m2n"
  }
}
POST /v1/clusters/{id}/upgrade Trigger a rolling upgrade

Initiates a zero-downtime rolling upgrade. NodeFoundry drains each OSD before upgrading the host.

Request body

FieldTypeRequiredDescription
ceph_versionstringNoTarget Ceph version, e.g. "squid".
os_packagesbooleanNoUpdate OS packages on all nodes.
max_concurrentintegerNoNodes to upgrade at once. Default: 1.
DELETE /v1/clusters/{id} Delete a cluster

Destroys all Ceph services and wipes OSD data. Nodes return to pending state. Irreversible.

Warning — Permanently destroys all data. Requires header X-Confirm-Delete: true.

Nodes

GET /v1/nodes List all nodes

Returns all registered nodes, including unassigned ones. Use ?cluster_id= to filter by cluster.

{
  "data": [
    {
      "id": "node_01abc",
      "hostname": "storage-01",
      "status": "online",
      "cluster_id": "clus_01hyfge4qpkx",
      "ip_address": "10.10.1.21",
      "ipmi_address": "10.10.2.21",
      "cpu_cores": 32,
      "ram_gb": 256,
      "drives": [
        { "device": "nvme0n1", "size_gb": 3840, "type": "nvme", "smart_ok": true }
      ]
    }
  ]
}
POST /v1/nodes/{id}/reboot Reboot a node

Triggers a graceful OS reboot via IPMI. Active OSDs are marked down before reboot and recover on return.

Request body

FieldTypeDescription
methodstring"graceful" (default) or "hard".
drain_osdsbooleanDrain OSDs before reboot. Default: true.

OSDs

GET /v1/clusters/{id}/osds List cluster OSDs
{
  "data": [
    {
      "osd_id": 0,
      "node_id": "node_01abc",
      "device": "nvme0n1",
      "status": "up",
      "in": true,
      "weight": 1.0,
      "capacity_gb": 3840,
      "used_gb": 1240
    }
  ]
}
POST /v1/clusters/{id}/osds/{osd_id}/reweight Reweight an OSD

Request body

FieldTypeDescription
weightfloatNew CRUSH weight. Range 0.01.0. Set to 0 to drain before removal.

Pools

POST /v1/clusters/{id}/pools Create a pool

Request body

FieldTypeRequiredDescription
namestringYesPool name.
typestringYes"replicated" or "erasure".
replication_factorintegerNoFor replicated pools. Default: 3.
erasure_profilestringNoNamed erasure code profile.
pg_autoscalebooleanNoEnable PG autoscaler. Default: true.
applicationstringNo"rbd", "cephfs", or "rgw".

Errors

All error responses share a consistent shape:

{
  "error": {
    "code": "node_not_found",
    "message": "No node with ID node_01xyz exists in this account.",
    "request_id": "req_01pqr9s"
  }
}
HTTP statusMeaning
400Bad request — invalid parameters
401Unauthorized — missing or invalid API key
403Forbidden — insufficient permissions
404Not found
409Conflict — e.g. cluster name already exists
429Rate limit exceeded
500Internal server error