---
title: "Delete a sandbox; its RAM-minute meter stops [rate class: sandbox_api_rps]"
method: DELETE
path: "/preview/sandboxes/{id}"
tags: ["sandboxes"]
---

# Delete a sandbox; its RAM-minute meter stops \[rate class: sandbox_api_rps\]

`DELETE /preview/sandboxes/{id}`

## Request

- Base URL: `https://autoresearch.sfcompute.com`
- URL: `https://autoresearch.sfcompute.com/preview/sandboxes/{id}`
- Auth: HTTP bearer

Delete sandboxes and stop their RAM-minute meters. SCOPE: microVMs you forked in your own workspace - disposable by design and re-forkable from their snapshot at any time, so a delete is the routine close of a fork's work, never a loss. Array-shaped, like sandbox_exec: pass sandboxes: [...] and tear down a whole batch in ONE call. A loop that deletes N forks one at a time pays N round trips for work that is one round trip; the array shape is not an optimization, it is the shape. Sandboxes bill for as long as they exist, so delete each fork the moment its work is scored - forks are disposable by design, because anything worth keeping should be a snapshot (snapshot_sandbox), not an idle sandbox. Deleting a sandbox never touches the snapshot it was forked from: re-fork an identical copy any time. Results come back in request order, one per entry, each carrying deleted: true|false - and a false entry is a sandbox that is STILL RUNNING AND STILL BILLING, either because the id was not yours or because the host refused the teardown. The call still succeeds when that happens, so check the entries, not just the status: `deleted` less than the number you sent means read them.

## Path parameters

- `id` string, nullable, required: Single-sandbox shorthand instead of a one-entry `sandboxes` array (from fork_sandbox / create_sandbox). Opaque - pass back the exact string you were given.

## Query parameters

- `workspace` string

## Request body

- object
  - `sandboxes` string[], nullable: The batch shape, and the one a loop should use: every sandbox to delete, in one call. One call for 128 forks instead of 128 calls.

## Response `200`

The capability's JSON result.

- Result: The capability's result: the same object the MCP tool returns as structuredContent. Resources carry an `object` type discriminator and an immutable id; money is integer micro-dollars in `*_usd_micros` fields.
  - `object` string: The resource type, when the result is one resource.

## Other responses

- `400`: Malformed request: bad JSON, a parameter that does not parse, or a value outside its range. Code `invalid`.
- `401`: No bearer token, or one this API cannot verify. Code `unauthenticated`.
- `403`: Authenticated, but the token's scopes or the account's role do not reach this operation. The message names the scope word to request. Code `forbidden`.
- `404`: No such route. Code `not_found`; the body names the OpenAPI document.
- `422`: A well-formed request the platform declined: no such node, a cap reached, a state that forbids the move. The message says which, and what to do instead. Code `refused`.
- `429`: Over this door's per-customer budget. Wait `Retry-After` seconds. Code `rate_limited`.
- `500`: Our fault. Retry; if it persists, quote the request-id. Code `internal`.

---

[API](https://skmtc.dev/givemeanode/apis/autoresearch-customer-api.md) · [All operations](https://skmtc.dev/givemeanode/apis/autoresearch-customer-api/llms.txt) · [OpenAPI document](https://skmtc.dev/givemeanode/apis/autoresearch-customer-api/revisions/f88dcb70ac6c?raw)
