ReferenceAPI

Clusters

Clusters API methods, requests, and responses for RawTree Cloud and RawTree BYOC.

Clusters

Organization administrators can create, update, stop, resume, and delete clusters. Members can read cluster details.

Cluster endpoints require an authenticated user session or OAuth access token. Pass the organization name as organization on every endpoint except the size catalog. Organization members can read clusters and metrics; organization admins are required to create, update, pause, resume, verify storage, or delete clusters.

Cluster responses use this shape:

{
  "id": "9f30c31c-74a7-4a08-aab0-494689ab5b31",
  "name": "production",
  "created_at": "2026-08-26 10:00:00+00",
  "status": {
    "phase": "ready",
    "ready": true,
    "message": null
  },
  "resources": {
    "shards": 1,
    "replicas": 2,
    "cpu_cores_per_replica": 2.0,
    "memory_bytes_per_replica": 8589934592,
    "minimum_size": { "cpu_cores": 2.0, "memory_bytes": 8589934592 },
    "maximum_size": { "cpu_cores": 64.0, "memory_bytes": 274877906944 }
  },
  "can_pause": true,
  "can_resume": false,
  "s3_storage": null,
  "s3_storage_access": {
    "external_id": "rawtree-5b71c457-7d83-474b-9db9-6dc48a1ec042",
    "resource_tag": "rawtree-dc1fb78e-341d-48f8-a183-9ecea12eb41d"
  },
  "idle_timeout_minutes": 15
}

resources can be null while resource information is unavailable. Use status.ready, can_pause, and can_resume instead of inferring lifecycle capabilities from the phase name.

s3_storage_access contains the saved, immutable external_id and resource_tag for this cluster's S3 storage access. The object is null for older clusters without a saved identity. resource_tag is the tag value for the fixed AWS tag key rawtree.com/cluster. s3_storage is null for service-managed defaults, or contains data and backups destinations for custom defaults. Both destinations always include bucket and path in responses; an empty path means the bucket root. Responses do not include the customer IAM role ARN.

GET /v1/clusters

List the organization's permanent clusters and their current status.

GET /v1/clusters?organization=acme

The response contains an array of cluster objects:

{
  "clusters": []
}

Use an API key, a permitted workload token, or a user bearer token. Database-role keys support only the operations listed in Authentication.

Parameters:

FieldLocationTypeRequiredNotes
organizationquerystringNoOrganization name; required for users, optional for API keys

Request:

# List permanent clusters and their current status.
curl -X GET "https://api.rawtree.com/v1/clusters" \
  -H "Authorization: Bearer $RAWTREE_API_KEY"

Expected response: HTTP 200.

{
  "clusters": [
    {
      "id": "33333333-3333-4333-8333-333333333333",
      "name": "production",
      "created_at": "2026-11-09T10:00:00Z",
      "status": {
        "phase": "ready",
        "ready": true,
        "label": "Ready",
        "message": null
      },
      "can_pause": true,
      "can_resume": false,
      "idle_timeout_minutes": 30
    }
  ]
}

Errors: 400, 401, 403. See API errors.

GET /v1/clusters/{cluster_id}

Get one cluster by the UUID returned from the cluster list.

GET /v1/clusters/9f30c31c-74a7-4a08-aab0-494689ab5b31?organization=acme

Use a user session or user OAuth token with full_access. API keys and workload tokens cannot use this method.

Parameters:

FieldLocationTypeRequiredNotes
organizationquerystringYesOrganization name

Request:

# Get a permanent cluster and its current status.
curl -X GET "https://api.rawtree.com/v1/clusters/33333333-3333-4333-8333-333333333333?organization=team_alpha" \
  -H "Authorization: Bearer $RAWTREE_USER_TOKEN"

Expected response: HTTP 200.

{
  "id": "33333333-3333-4333-8333-333333333333",
  "name": "production",
  "created_at": "2026-11-09T10:00:00Z",
  "status": {
    "phase": "ready",
    "ready": true,
    "label": "Ready",
    "message": null
  },
  "can_pause": true,
  "can_resume": false,
  "idle_timeout_minutes": 30
}

Errors: 401, 403, 404. See API errors.

GET /v1/clusters/sizes

List the supported per-replica resource sizes, replica limits, and default autoscaling bounds. Call this endpoint before creating a cluster and pass one of its cpu_cores and memory_gib pairs back to the create endpoint.

{
  "min_number_of_replicas": 1,
  "max_number_of_replicas": 2,
  "sizes": [
    { "size": "large", "cpu_cores": 2, "memory_gib": 8 },
    { "size": "xlarge", "cpu_cores": 4, "memory_gib": 16 }
  ],
  "default_min_size": { "size": "large", "cpu_cores": 2, "memory_gib": 8 },
  "default_max_size": { "size": "xlarge", "cpu_cores": 4, "memory_gib": 16 }
}

The size label is for display. The resource pair is the stable create input.

Use a user session or user OAuth token with full_access. API keys and workload tokens cannot use this method.

Request:

# List cluster sizes and replica limits.
curl -X GET "https://api.rawtree.com/v1/clusters/sizes?organization=team_alpha" \
  -H "Authorization: Bearer $RAWTREE_USER_TOKEN"

Expected response: HTTP 200.

{
  "min_number_of_replicas": 1,
  "max_number_of_replicas": 1,
  "sizes": [
    {
      "size": "2 CPU / 8 GiB",
      "cpu_cores": 2,
      "memory_gib": 8
    }
  ],
  "default_min_size": {
    "size": "2 CPU / 8 GiB",
    "cpu_cores": 2,
    "memory_gib": 8
  },
  "default_max_size": {
    "size": "2 CPU / 8 GiB",
    "cpu_cores": 2,
    "memory_gib": 8
  }
}

Errors: 401. See API errors.

POST /v1/clusters

Create a cluster. name, region_id, replicas, and size are required. Choose region_id from GET /v1/regions. The API resolves the deployment. Callers do not need a deployment ID or routing headers.

The API rejects missing or null region IDs. Disabled regions and regions without a usable deployment cannot create clusters. The API does not select another region.

s3_storage_access is optional. Omit it, pass null, or omit either of its external_id and resource_tag fields to let the API generate the missing values as independent rawtree-<UUID> identities. Custom s3_storage requires an explicit s3_storage_access.external_id matching the IAM trust policy. autoscaling, idle_timeout_minutes, and s3_storage are optional.

POST /v1/clusters?organization=acme
{
  "name": "production",
  "region_id": "11111111-1111-4111-8111-111111111111",
  "replicas": 2,
  "size": { "cpu_cores": 2, "memory_gib": 8 },
  "autoscaling": {
    "min_size": { "cpu_cores": 2, "memory_gib": 8 },
    "max_size": { "cpu_cores": 8, "memory_gib": 32 }
  },
  "idle_timeout_minutes": 15
}

Set idle_timeout_minutes to 0 to disable automatic idling, or use a value from 15 through 43,200 minutes. Omit it to use the configured default. When autoscaling is omitted, the size catalog's default_min_size and default_max_size are used. The initial size must fall within those bounds.

To use customer-owned S3 storage, include s3_storage:

{
  "name": "production",
  "region_id": "11111111-1111-4111-8111-111111111111",
  "replicas": 2,
  "size": {
    "cpu_cores": 2,
    "memory_gib": 8
  },
  "s3_storage_access": {
    "external_id": "rawtree-5b71c457-7d83-474b-9db9-6dc48a1ec042",
    "resource_tag": "rawtree-dc1fb78e-341d-48f8-a183-9ecea12eb41d"
  },
  "s3_storage": {
    "data": { "bucket": "acme-rawtree-data", "path": "rawtree/data" },
    "backups": { "bucket": "acme-rawtree-backups", "path": "rawtree/backups" },
    "role_arn": "arn:aws:iam::123456789012:role/RawTreeS3Access"
  }
}

Tables created normally use the cluster's configured storage. If cluster creation returns an ambiguous response, list clusters and look for the requested name before retrying.

Omit s3_storage or set it to null to use service-managed cluster defaults. A custom s3_storage requires both data and backups, each with a bucket, plus role_arn. Paths are optional and default to the bucket root. The two buckets cannot be configured independently as custom and managed storage.

The API generates and saves missing identity values once at cluster creation. Clients may supply explicit values when preparing IAM policies; the dashboard keeps the values shown during setup when you switch storage modes. Read the saved identity from s3_storage_access in the cluster response. Use the External ID in the customer IAM role's trust policy. resource_tag contains the value for the fixed AWS tag key rawtree.com/cluster. For custom database storage, apply rawtree.com/cluster=<resource_tag> to both buckets and the customer IAM role. These identity values cannot be changed after cluster creation. Top-level external_id, resource_tag, and the old database_s3_access block are not accepted.

Use a user session or user OAuth token with full_access. API keys and workload tokens cannot use this method.

Parameters:

FieldLocationTypeRequiredNotes
organizationquerystringYesOrganization name
namebodystringYes—
region_idbodystringYesRegion from /v1/regions. The API resolves its deployment internally.
replicasbodyintegerYes—
sizebodyCreateClusterSizeYesResources per replica, one of the sizes returned by /v1/clusters/sizes.
idle_timeout_minutesbodyinteger or nullNoMinutes without activity before automatically pausing. Omit to use the configured default.
cluster_idbodystring or nullNoOptional client-generated cluster UUID. Omit to let the backend generate one.
autoscalingbodynull or CreateClusterAutoscalingNo—
s3_storagebodynull or S3StorageInputNo—
s3_storage_accessbodynull or S3StorageAccessInputNo—

Request:

# Create a permanent cluster.
curl -X POST "https://api.rawtree.com/v1/clusters?organization=team_alpha" \
  -H "Authorization: Bearer $RAWTREE_USER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "production",
  "region_id": "11111111-1111-4111-8111-111111111111",
  "replicas": 2,
  "size": {
    "cpu_cores": 2,
    "memory_gib": 8
  }
}'

Expected response: HTTP 200.

{
  "id": "33333333-3333-4333-8333-333333333333",
  "name": "production",
  "created_at": "2026-11-09T10:00:00Z",
  "status": {
    "phase": "unknown",
    "ready": false,
    "label": "Unknown",
    "message": null
  },
  "can_pause": false,
  "can_resume": false,
  "idle_timeout_minutes": 30
}

Errors: 400, 401, 403. See API errors.

POST /v1/clusters/verify-s3-access

Verify that the service can assume the configured role and access both S3 destinations before creating the cluster. The s3_storage object has the same shape as the create request. This pre-creation check also requires the proposed s3_storage_access.external_id because the cluster has no saved identity yet. Verification does not save it.

POST /v1/clusters/verify-s3-access?organization=acme
{
  "s3_storage_access": {
    "external_id": "rawtree-5b71c457-7d83-474b-9db9-6dc48a1ec042"
  },
  "s3_storage": {
    "data": { "bucket": "acme-rawtree-data", "path": "rawtree/data" },
    "backups": { "bucket": "acme-rawtree-backups", "path": "rawtree/backups" },
    "role_arn": "arn:aws:iam::123456789012:role/RawTreeS3Access"
  }
}
{ "verified": true, "message": "S3 access verified." }

Use a user session or user OAuth token with full_access. API keys and workload tokens cannot use this method.

Parameters:

FieldLocationTypeRequiredNotes
organizationquerystringYesOrganization name
s3_storage_accessbodyS3StorageAccessInputYesThe proposed identity; external_id must match the customer IAM trust policy.
s3_storagebodyS3StorageInputYes—

Request:

# Verify customer-owned S3 access for cluster creation.
curl -X POST "https://api.rawtree.com/v1/clusters/verify-s3-access?organization=team_alpha" \
  -H "Authorization: Bearer $RAWTREE_USER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "s3_storage_access": {
    "external_id": "rawtree-docs-example",
    "resource_tag": "33333333-3333-4333-8333-333333333333"
  },
  "s3_storage": {
    "data": {
      "bucket": "acme-rawtree-data",
      "path": "rawtree/data"
    },
    "backups": {
      "bucket": "acme-rawtree-backups",
      "path": "rawtree/backups"
    },
    "role_arn": "arn:aws:iam::123456789012:role/RawTreeS3Access"
  }
}'

Expected response: HTTP 200.

{
  "verified": true,
  "message": "S3 access verified."
}

Errors: 400, 401, 403. See API errors.

PATCH /v1/clusters/{cluster_id}

Update the cluster name, automatic idle timeout, or both. Omitted properties are unchanged.

PATCH /v1/clusters/9f30c31c-74a7-4a08-aab0-494689ab5b31?organization=acme
{
  "name": "primary",
  "idle_timeout_minutes": 60
}

Use idle_timeout_minutes: 0 to disable automatic idling.

Use a user session or user OAuth token with full_access. API keys and workload tokens cannot use this method.

Parameters:

FieldLocationTypeRequiredNotes
organizationquerystringYesOrganization name
namebodystring or nullNo—
idle_timeout_minutesbodyinteger or nullNo—

Request:

# Update cluster settings.
curl -X PATCH "https://api.rawtree.com/v1/clusters/33333333-3333-4333-8333-333333333333?organization=team_alpha" \
  -H "Authorization: Bearer $RAWTREE_USER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "idle_timeout_minutes": 30
}'

Expected response: HTTP 200.

{
  "id": "33333333-3333-4333-8333-333333333333",
  "name": "production",
  "created_at": "2026-11-09T10:00:00Z",
  "status": {
    "phase": "unknown",
    "ready": false,
    "label": "Unknown",
    "message": null
  },
  "can_pause": false,
  "can_resume": false,
  "idle_timeout_minutes": 30
}

Errors: 400, 401, 403, 404. See API errors.

POST /v1/clusters/{cluster_id}/stop

Request that a running cluster pause. The response is the updated cluster object; use its status and can_pause/can_resume fields to follow the transition.

Use a user session or user OAuth token with full_access. API keys and workload tokens cannot use this method.

Parameters:

FieldLocationTypeRequiredNotes
organizationquerystringYesOrganization name

Request:

# Stop a cluster.
curl -X POST "https://api.rawtree.com/v1/clusters/33333333-3333-4333-8333-333333333333/stop?organization=team_alpha" \
  -H "Authorization: Bearer $RAWTREE_USER_TOKEN"

Expected response: HTTP 200.

{
  "id": "33333333-3333-4333-8333-333333333333",
  "name": "production",
  "created_at": "2026-11-09T10:00:00Z",
  "status": {
    "phase": "unknown",
    "ready": false,
    "label": "Unknown",
    "message": null
  },
  "can_pause": false,
  "can_resume": false,
  "idle_timeout_minutes": 30
}

Errors: 400, 401, 403, 404, 409. See API errors.

POST /v1/clusters/{cluster_id}/resume

Request that a paused cluster resume. The response is the updated cluster object. A conflicting lifecycle transition returns 409.

Use a user session or user OAuth token with full_access. API keys and workload tokens cannot use this method.

Parameters:

FieldLocationTypeRequiredNotes
organizationquerystringYesOrganization name

Request:

# Resume a cluster.
curl -X POST "https://api.rawtree.com/v1/clusters/33333333-3333-4333-8333-333333333333/resume?organization=team_alpha" \
  -H "Authorization: Bearer $RAWTREE_USER_TOKEN"

Expected response: HTTP 200.

{
  "id": "33333333-3333-4333-8333-333333333333",
  "name": "production",
  "created_at": "2026-11-09T10:00:00Z",
  "status": {
    "phase": "unknown",
    "ready": false,
    "label": "Unknown",
    "message": null
  },
  "can_pause": false,
  "can_resume": false,
  "idle_timeout_minutes": 30
}

Errors: 400, 401, 403, 404, 409. See API errors.

DELETE /v1/clusters/{cluster_id}

Permanently delete a cluster.

{ "deleted": true }

Use a user session or user OAuth token with full_access. API keys and workload tokens cannot use this method.

Parameters:

FieldLocationTypeRequiredNotes
organizationquerystringYesOrganization name

Request:

# Permanently delete a cluster.
curl -X DELETE "https://api.rawtree.com/v1/clusters/33333333-3333-4333-8333-333333333333?organization=team_alpha" \
  -H "Authorization: Bearer $RAWTREE_USER_TOKEN"

Expected response: HTTP 200.

{
  "deleted": true
}

Errors: 400, 401, 403, 404. See API errors.