+++
title = "Plans, regions, spaces and releases"
description = "What a cluster can be created with."
weight = 90
updated = 2026-11-03

[extra]
nav_title = "Plans and regions"
weight = 60
+++

<!-- Generated by script/build-api-reference.js from data/openapi/v1.yml and data/api-reference/pages.yml. Edit those and run `npm run build:api-reference`, not this file. -->

What a cluster can be created with. Plans differ by account, so these
lists show what this account can use. A plan's `offers` say which
releases it has in each region. Private spaces are only for accounts
with private placement; everyone else picks a region.

**On this page:** [Plan object](#plan-object), [Region object](#region-object), [Space object](#space-object), [Release object](#release-object), [List the plans this account can choose](#list-plans), [Show a plan](#get-plan), [List the regions clusters can be created in](#list-regions), [List the account's private spaces](#list-spaces), [List the releases this account can choose](#list-releases).

## The Plan object {#plan-object}

| Field | Type | Description |
|---|---|---|
| `id` | string | Its ID. Never changes. |
| `name` | string | The plan's name. |
| `price_in_cents` | integer | The price per billing interval, in US cents. |
| `billing_interval_months` | integer | Months in each billing interval. |
| `single_tenant` | boolean | Whether clusters on it run on servers of their own. |
| `private_network` | boolean | Whether clusters on it are on a private network. |
| `regions` | array of strings | Region IDs this plan can be created in: the regions of `offers`. |
| `releases` | array of strings | Release IDs this plan can be created with in some region: every release of `offers`, in offer order. |
| `offers` | array of objects | Where this plan can be created, and with which releases in each region. Empty when the plan is offered nowhere. |
| `offers[].region` | string | Region ID. |
| `offers[].releases` | array of strings | Release IDs offered in this region, OpenSearch first, then newest first. A create that names no release gets the first one its space can place. |

```json
{
  "id": "sandbox",
  "name": "Sandbox",
  "price_in_cents": 0,
  "billing_interval_months": 1,
  "single_tenant": false,
  "private_network": false,
  "regions": ["aws-us-east-1", "aws-eu-west-1"],
  "releases": ["opensearch-3.8.0", "elasticsearch-7.10.2"],
  "offers": [
    {
      "region": "aws-us-east-1",
      "releases": ["opensearch-3.8.0", "elasticsearch-7.10.2"]
    },
    { "region": "aws-eu-west-1", "releases": ["opensearch-3.8.0"] }
  ]
}
```

## The Region object {#region-object}

| Field | Type | Description |
|---|---|---|
| `id` | string | e.g. `aws-us-east-1`. |
| `name` | string | The region's name. |
| `cloud` | string | One of `aws`, `gcp`. More may be added. |
| `cloud_region` | string | The provider's own name, e.g. `us-east-1`. |

```json
{
  "id": "aws-us-east-1",
  "name": "AWS US East (N. Virginia)",
  "cloud": "aws",
  "cloud_region": "us-east-1"
}
```

## The Space object {#space-object}

| Field | Type | Description |
|---|---|---|
| `id` | string | Its ID. Never changes. |
| `name` | string | The space's name. |
| `region` | string | Region ID. |
| `private_network` | boolean | Whether the space is on a private network. |

```json
{
  "id": "acme-private-us-east-1",
  "name": "Acme private (us-east-1)",
  "region": "aws-us-east-1",
  "private_network": true
}
```

## The Release object {#release-object}

| Field | Type | Description |
|---|---|---|
| `id` | string | e.g. `opensearch-3.8.0`. |
| `name` | string | The release's name. |
| `engine` | string | One of `elasticsearch`, `opensearch`. More may be added. |
| `version` | string | The engine's version. |

```json
{
  "id": "opensearch-3.8.0",
  "name": "OpenSearch 3.8.0",
  "engine": "opensearch",
  "version": "3.8.0"
}
```

## List the plans this account can choose {#list-plans}

<p class="api-endpoint"><span class="api-method api-method-get">GET</span> <code>/v1/plans</code></p>

- **Scope:** `account:read`

Plans differ by account; this lists the ones this account may use that are offered somewhere.

### Parameters

| Name | In | Type | Description |
|---|---|---|---|
| `limit` | query | integer | Page size. Defaults to 25. |
| `cursor` | query | string | The `next_cursor` of the previous page. Opaque. |

### Example request

```bash
curl https://api.bonsai.io/v1/plans \
  -H "Authorization: Bearer $BONSAI_TOKEN"
```

### Response

`200 OK`. A page of [Plan objects](#plan-object) in `data`, with `next_cursor`. See [Pagination](@/docs/api/requests-and-responses/index.md#pagination).

```json
{
  "data": [
    {
      "id": "sandbox",
      "name": "Sandbox",
      "price_in_cents": 0,
      "billing_interval_months": 1,
      "single_tenant": false,
      "private_network": false,
      "regions": ["aws-us-east-1", "aws-eu-west-1"],
      "releases": ["opensearch-3.8.0", "elasticsearch-7.10.2"],
      "offers": [
        {
          "region": "aws-us-east-1",
          "releases": ["opensearch-3.8.0", "elasticsearch-7.10.2"]
        },
        { "region": "aws-eu-west-1", "releases": ["opensearch-3.8.0"] }
      ]
    }
  ],
  "next_cursor": null
}
```

### Errors

| Status | Codes |
|---|---|
| `400` | [`invalid_parameter`](@/docs/api/errors/index.md#invalid_parameter) |
| `401` | [`unauthorized`](@/docs/api/errors/index.md#unauthorized) |
| `403` | [`missing_scope`](@/docs/api/errors/index.md#missing_scope) |
| `429` | [`rate_limited`](@/docs/api/errors/index.md#rate_limited), [`too_many_failed_authentications`](@/docs/api/errors/index.md#too_many_failed_authentications) |

## Show a plan {#get-plan}

<p class="api-endpoint"><span class="api-method api-method-get">GET</span> <code>/v1/plans/{plan_id}</code></p>

- **Scope:** `account:read`

404 if the plan isn't available to this account. A plan offered nowhere is answered, with empty `offers`.

### Parameters

| Name | In | Type | Description |
|---|---|---|---|
| `plan_id` | path | string | Required. |

### Example request

```bash
curl https://api.bonsai.io/v1/plans/sandbox \
  -H "Authorization: Bearer $BONSAI_TOKEN"
```

### Response

`200 OK`. The plan. Returns a [Plan object](#plan-object).

```json
{
  "id": "sandbox",
  "name": "Sandbox",
  "price_in_cents": 0,
  "billing_interval_months": 1,
  "single_tenant": false,
  "private_network": false,
  "regions": ["aws-us-east-1", "aws-eu-west-1"],
  "releases": ["opensearch-3.8.0", "elasticsearch-7.10.2"],
  "offers": [
    {
      "region": "aws-us-east-1",
      "releases": ["opensearch-3.8.0", "elasticsearch-7.10.2"]
    },
    { "region": "aws-eu-west-1", "releases": ["opensearch-3.8.0"] }
  ]
}
```

### Errors

| Status | Codes |
|---|---|
| `401` | [`unauthorized`](@/docs/api/errors/index.md#unauthorized) |
| `403` | [`missing_scope`](@/docs/api/errors/index.md#missing_scope) |
| `404` | [`not_found`](@/docs/api/errors/index.md#not_found) |
| `429` | [`rate_limited`](@/docs/api/errors/index.md#rate_limited), [`too_many_failed_authentications`](@/docs/api/errors/index.md#too_many_failed_authentications) |

## List the regions clusters can be created in {#list-regions}

<p class="api-endpoint"><span class="api-method api-method-get">GET</span> <code>/v1/regions</code></p>

- **Scope:** `account:read`

The regions some plan of this account can be created in.

### Parameters

| Name | In | Type | Description |
|---|---|---|---|
| `limit` | query | integer | Page size. Defaults to 25. |
| `cursor` | query | string | The `next_cursor` of the previous page. Opaque. |

### Example request

```bash
curl https://api.bonsai.io/v1/regions \
  -H "Authorization: Bearer $BONSAI_TOKEN"
```

### Response

`200 OK`. A page of [Region objects](#region-object) in `data`, with `next_cursor`. See [Pagination](@/docs/api/requests-and-responses/index.md#pagination).

```json
{
  "data": [
    {
      "id": "aws-us-east-1",
      "name": "AWS US East (N. Virginia)",
      "cloud": "aws",
      "cloud_region": "us-east-1"
    }
  ],
  "next_cursor": null
}
```

### Errors

| Status | Codes |
|---|---|
| `400` | [`invalid_parameter`](@/docs/api/errors/index.md#invalid_parameter) |
| `401` | [`unauthorized`](@/docs/api/errors/index.md#unauthorized) |
| `403` | [`missing_scope`](@/docs/api/errors/index.md#missing_scope) |
| `429` | [`rate_limited`](@/docs/api/errors/index.md#rate_limited), [`too_many_failed_authentications`](@/docs/api/errors/index.md#too_many_failed_authentications) |

## List the account's private spaces {#list-spaces}

<p class="api-endpoint"><span class="api-method api-method-get">GET</span> <code>/v1/spaces</code></p>

- **Scope:** `account:read`

The account's private spaces that some plan can be created in. Empty for accounts without private placement. Shared spaces are not listed; pick a region instead.

### Parameters

| Name | In | Type | Description |
|---|---|---|---|
| `limit` | query | integer | Page size. Defaults to 25. |
| `cursor` | query | string | The `next_cursor` of the previous page. Opaque. |

### Example request

```bash
curl https://api.bonsai.io/v1/spaces \
  -H "Authorization: Bearer $BONSAI_TOKEN"
```

### Response

`200 OK`. A page of [Space objects](#space-object) in `data`, with `next_cursor`. See [Pagination](@/docs/api/requests-and-responses/index.md#pagination).

```json
{
  "data": [
    {
      "id": "acme-private-us-east-1",
      "name": "Acme private (us-east-1)",
      "region": "aws-us-east-1",
      "private_network": true
    }
  ],
  "next_cursor": null
}
```

### Errors

| Status | Codes |
|---|---|
| `400` | [`invalid_parameter`](@/docs/api/errors/index.md#invalid_parameter) |
| `401` | [`unauthorized`](@/docs/api/errors/index.md#unauthorized) |
| `403` | [`missing_scope`](@/docs/api/errors/index.md#missing_scope) |
| `429` | [`rate_limited`](@/docs/api/errors/index.md#rate_limited), [`too_many_failed_authentications`](@/docs/api/errors/index.md#too_many_failed_authentications) |

## List the releases this account can choose {#list-releases}

<p class="api-endpoint"><span class="api-method api-method-get">GET</span> <code>/v1/releases</code></p>

- **Scope:** `account:read`

The releases some plan of this account can be created with, OpenSearch first, then newest first.

### Parameters

| Name | In | Type | Description |
|---|---|---|---|
| `limit` | query | integer | Page size. Defaults to 25. |
| `cursor` | query | string | The `next_cursor` of the previous page. Opaque. |

### Example request

```bash
curl https://api.bonsai.io/v1/releases \
  -H "Authorization: Bearer $BONSAI_TOKEN"
```

### Response

`200 OK`. A page of [Release objects](#release-object) in `data`, with `next_cursor`. See [Pagination](@/docs/api/requests-and-responses/index.md#pagination).

```json
{
  "data": [
    {
      "id": "opensearch-3.8.0",
      "name": "OpenSearch 3.8.0",
      "engine": "opensearch",
      "version": "3.8.0"
    }
  ],
  "next_cursor": null
}
```

### Errors

| Status | Codes |
|---|---|
| `400` | [`invalid_parameter`](@/docs/api/errors/index.md#invalid_parameter) |
| `401` | [`unauthorized`](@/docs/api/errors/index.md#unauthorized) |
| `403` | [`missing_scope`](@/docs/api/errors/index.md#missing_scope) |
| `429` | [`rate_limited`](@/docs/api/errors/index.md#rate_limited), [`too_many_failed_authentications`](@/docs/api/errors/index.md#too_many_failed_authentications) |
