+++
title = "Actions"
weight = 80
updated = 2026-11-03

[extra]
nav_title = "Actions"
weight = 30
+++

Some changes to a cluster take longer than a request should wait. In the Bonsai API v1, these run as **Actions**: the request starts the work and answers `202 Accepted` at once, and you poll the Action to follow it.

| To | Call | Starts |
|---|---|---|
| [Create a cluster](@/docs/api/reference/clusters/index.md#create-cluster) | `POST /v1/clusters` | <code class="nowrap">cluster.provision</code> |
| [Delete a cluster](@/docs/api/reference/clusters/index.md#delete-cluster) | `DELETE /v1/clusters/{cluster_id}?name=` | <code class="nowrap">cluster.deprovision</code> |
| [Change a cluster's plan](@/docs/api/reference/clusters/index.md#change-cluster-plan) | `POST /v1/clusters/{cluster_id}/plan_changes` | <code class="nowrap">cluster.change_plan</code> |

Renaming a cluster, and creating or revoking a credential, are quick, so they answer right away and start no Action.

## Following an Action

The `202` response is the Action, and its `Location` header is the Action's URL. Poll that URL until the Action's `state` is `success` or `error`:

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

While the Action is unfinished, the response has a `Retry-After` header with the seconds to wait before the next poll. Polling more often doesn't make the Action go faster, and it uses up your [rate limit](@/docs/api/rate-limits/index.md).

An Action's `state` is one of:

| State | Meaning |
|---|---|
| `new` | Started, and waiting to run. |
| `running` | Running. |
| `success` | Finished. |
| `error` | Failed. `error` says why. |

An Action also has a `subject`, the cluster it acts on, and a list of `steps`, each with its own `state`, a `message` and a time.

## Results

When an Action that creates something succeeds, its `result` names what it made. For `cluster.provision`, that's the new cluster and its first credential:

```json
{
  "id": "act_3k9x0q2m7v1c8b4n",
  "type": "cluster.provision",
  "state": "success",
  "subject": { "type": "cluster", "id": "my-search-4823919" },
  "created_at": "2026-10-26T14:03:00Z",
  "finished_at": "2026-10-26T14:03:06Z",
  "error": null,
  "result": { "cluster": "my-search-4823919", "credential": "scc-a8Kd" },
  "steps": []
}
```

Get the credential, with its password and URL, from [`GET /v1/clusters/{cluster_id}/credentials/{credential_id}`](@/docs/api/reference/credentials/index.md#get-cluster-credential). That needs the `credentials:read` scope.

## Failures

A failed Action has `state` `error`, and an `error` with a `code` and a `message`. Branch on `code`. The message is for people, and can change.

| Code | Meaning |
|---|---|
| `timed_out` | The Action stopped making progress. |
| `action_failed` | Anything else. Bonsai support can see what went wrong. |
| `payment_failed` | Bonsai couldn't charge the account, so billing for the cluster couldn't start. `error.action_url` is where a card can be added. Only Actions started through the legacy API fail this way. A v1 create charges before it builds, and answers a refused charge at once with [`422 payment_failed`](@/docs/api/errors/index.md#payment_failed). |

More codes may be added, so treat a code you don't know like `action_failed`.

If a cluster fails to build, Bonsai stops billing for it.

## One change at a time

A cluster runs one Action of a kind at a time. Starting another while one is running gets a [`409 action_in_progress`](@/docs/api/errors/index.md#action_in_progress). Wait for the running one to finish, then try again.

## Actions Bonsai starts

Bonsai starts some Actions on its own: `cluster.read_only`, `cluster.disable` and `cluster.enable`. They show up in a cluster's Action list alongside yours, so a client that lists Actions sees them too. More types may be added, so handle a type you don't know.

To list a cluster's Actions, newest first:

```bash
curl -s https://api.bonsai.io/v1/clusters/my-search-4823919/actions \
  -H "Authorization: Bearer $BONSAI_TOKEN"
```

The [Action object](@/docs/api/reference/actions/index.md#action-object) lists every field. A cluster's `latest_action` also shows its most recent Action's ID, type and state.

## Retrying safely

Creating a cluster, deleting one and changing its plan all take an `Idempotency-Key`, so a retry gets the same Action back instead of starting a second one. See [Retrying safely](@/docs/api/retrying-safely/index.md).
