> ## Documentation Index
> Fetch the complete documentation index at: https://docs.beta.b3os.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Snapshot a sandbox

Saves the sandbox's memory and disk as a snapshot you can create new sandboxes from. The sandbox keeps running (it pauses for the copy). New sandboxes restored from a snapshot get a fresh identity, so two of them never share random state. Writing the snapshot resets the sandbox's open connections to the outside (open PTY sessions, streaming execs and log streams, port preview connections, outbound TCP connections); new ones work as soon as the call returns.
Snapshots are kept 7 days. An organization keeps at most `sandboxes.snapshots_max` snapshots (beta: 20) per node, counting at most `sandboxes.snapshot_storage_max` (beta: 40 GiB). Each snapshot counts its sandbox's memory plus its disk size: the memory is stored whole, and the disk copy comes to hold every block the sandbox rewrites after the snapshot. Past either limit the snapshot is refused with `422 limit_exceeded` until you delete some. While the node's snapshot store is nearly full, snapshots and forks are refused with `503 capacity_unavailable`. 

` POST /v1/sandboxes/{sandbox_id}/snapshot `

Snapshot a sandbox

Saves the sandbox's memory and disk as a snapshot you can create new sandboxes from. The sandbox keeps
running (it pauses for the copy). New sandboxes restored from a snapshot get a fresh identity, so two of them
never share random state. Writing the snapshot resets the sandbox's open connections to the outside (open
PTY sessions, streaming execs and log streams, port preview connections, outbound TCP connections); new
ones work as soon as the call returns.

Snapshots are kept 7 days. An organization keeps at most `sandboxes.snapshots_max` snapshots (beta: 20)
per node, counting at most `sandboxes.snapshot_storage_max` (beta: 40 GiB). Each snapshot counts its
sandbox's memory plus its disk size: the memory is stored whole, and the disk copy comes to hold every
block the sandbox rewrites after the snapshot. Past either limit the snapshot is refused with
`422 limit_exceeded` until you delete some. While the node's snapshot store is nearly full, snapshots and
forks are refused with `503 capacity_unavailable`.


## Servers

- ` https://beta-api.b3os.org ` — API (API keys and CLI tokens)

- ` https://beta.b3os.org ` — Dashboard (session cookie and CSRF header; same paths)

## Authentication

The operation accepts these alternatives. Schemes within one alternative are required together.

### Alternative 1

- ` apiKey `: ` http `

  - HTTP scheme: ` bearer ` (b3os_sk_ API key or b3os_pat_ token)

  - `Authorization: Bearer <credential>`. Two credential kinds are accepted:

- **API keys** `b3os_sk_<32 base32>_<crc32>`, created in the dashboard or with `POST /v1/keys`. A key belongs to
  one project, has scopes, an optional spend cap and expiry, and is shown only once.
- **CLI tokens** `b3os_pat_<32 base32>_<crc32>`, issued by the device login (`b3os login`). They act for one
  user in the organization and project chosen at approval.

Keys are stored as SHA-256 hashes. The edge exchanges them for a 60-second node token before forwarding
a request to a node, so nodes never see your key.


### Alternative 2

- ` session `: ` apiKey `

  - Credential: ` __Host-b3os_session ` in ` cookie `

  - The dashboard session cookie on `beta.b3os.org` (host-only, `Secure`, `HttpOnly`). Requests other than
`GET`/`HEAD` must also send `x-b3os-csrf: <csrf_token>` from `GET /v1/auth/session`; SameSite is not relied
on. The cookie is never sent to `beta-api.b3os.org` or `usercontent.b3os.org`.


## Parameters

### ` sandbox_id ` (path, required)

The sandbox ID (`sbx_…`).

- ` value `: type ` string `

  - pattern: ` "^sbx_[0-9a-hjkmnp-tv-z]{26}$" `

Example:

```json
"sbx_01m5t68q1b590rj801nbzsqzkk"
```

### ` Idempotency-Key ` (header, optional)

A unique value (for example a UUID) that makes this request safe to retry. Scoped to your project for 24
hours: a retry with the same key, method, path and body returns the stored response with
`Idempotent-Replayed: true`, and only to the same API key. Reusing the key for a different request returns
`409 idempotency_key_conflict`.


- ` value `: type ` string `

  - minLength: ` 1 `

  - maxLength: ` 255 `

## Request body (optional)

Content type: ` application/json `

- ` value `: type ` object `

  - ` name `: type ` string `

    - maxLength: ` 100 `

  - ` metadata `: type ` object ` — Up to 16 string key-value pairs you attach to an object for your own use. Keys are 1 to 40 characters of `A-Z a-z 0-9 _ . : -`; values are at most 500 characters. B3OS never interprets them. 

    - example: ` {"customer":"acme","ticket":"ENG-1423"} `

Example:

```json
{
  "name": "deps-installed"
}
```

## Responses

### ` 201 ` — The snapshot.

Content type: ` application/json `

- ` value `: type ` object `

  - Required fields: ` id `, ` object `, ` status `, ` sandbox_id `, ` template `, ` vcpu `, ` memory_mib `, ` disk_gib `, ` size_bytes `, ` created_at `, ` expires_at `, ` metadata `

  - ` id `: type ` string `

    - pattern: ` "^snap_[0-9a-hjkmnp-tv-z]{26}$" `

  - ` object `: type ` string `

    - enum: ` ["snapshot"] `

  - ` name `: type ` string `; nullable

  - ` status `: type ` string `

    - enum: ` ["creating","ready","failed"] `

  - ` sandbox_id `: type ` string `

  - ` template `: type ` object `

    - Required fields: ` id `, ` name `

    - ` id `: type ` string `

      - pattern: ` "^tpl_[0-9a-hjkmnp-tv-z]{26}$" `

    - ` name `: type ` string `

  - ` vcpu `: type ` integer `

  - ` memory_mib `: type ` integer `

  - ` disk_gib `: type ` integer `

  - ` size_bytes `: type ` integer `

  - ` created_at `: type ` string `; format ` date-time `

  - ` expires_at `: type ` string `; nullable; format ` date-time ` — When the snapshot is deleted (7 days in the beta).

  - ` timing `: type ` object ` — Server-side phase durations in milliseconds with microsecond resolution: the same phases as the `Server-Timing` header, keyed `<phase>_ms`. `total_ms` is always present. Phase names are product-specific and documented per operation. Example values in this reference are illustrative, not measurements. 

    - example: ` {"claim_ms":1.1,"navigate_ms":31,"extract_ms":4.2,"total_ms":36.6} `

    - Required fields: ` total_ms `

    - ` total_ms `: type ` number `

      - minimum: ` 0 `

  - ` metadata `: type ` object ` — Up to 16 string key-value pairs you attach to an object for your own use. Keys are 1 to 40 characters of `A-Z a-z 0-9 _ . : -`; values are at most 500 characters. B3OS never interprets them. 

    - example: ` {"customer":"acme","ticket":"ENG-1423"} `

Response header ` x-request-id ` — The request ID (`req_…`). It is the `instance` of any problem and the key for `GET /v1/requests/{request_id}`.

- ` value `: type ` string `

  - pattern: ` "^req_[0-9a-hjkmnp-tv-z]{26}$" `

Response header ` Server-Timing ` — Phase durations in milliseconds (W3C Server Timing); the handler's phases break the request down. For a
response whose body size is known, `total` runs from reading the request head to writing the response head.
Streaming responses (event streams, WebSockets, chunked bodies) carry no `total` here: they report their
final phases in the terminal event (`job.succeeded`, `job.failed`, `job.canceled`) or the final job. The
time from the first request byte to the last response byte is recorded in the node's metrics and request
log (`GET /v1/requests/{request_id}`). The edge prepends `edge_auth` and `edge_upstream`.


- ` value `: type ` string `

Response header ` Idempotent-Replayed ` — Present with the value `true` when the response is a stored replay of an earlier request with the same `Idempotency-Key`.

- ` value `: type ` string `

  - enum: ` ["true"] `

Example:

```json
{
  "id": "snap_01m5t5mnvax7tp9peav8jajw3y",
  "object": "snapshot",
  "name": "deps-installed",
  "status": "ready",
  "sandbox_id": "sbx_01m5t68q1b590rj801nbzsqzkk",
  "template": {
    "id": "tpl_01m5t59b2ps0djyzdf082s18bz",
    "name": "base"
  },
  "vcpu": 2,
  "memory_mib": 2048,
  "disk_gib": 4,
  "size_bytes": 734003200,
  "created_at": "2026-10-25T19:03:00.000Z",
  "expires_at": "2026-11-01T19:03:00.000Z",
  "timing": {
    "pause_ms": 0.5,
    "write_ms": 820.4,
    "total_ms": 823.1
  },
  "metadata": {}
}
```

### ` 400 ` — The request failed validation (`invalid_request`, `invalid_url`).

Content type: ` application/problem+json `

- ` value `: type ` object ` — An RFC 9457 problem. `code` is stable and listed in the errors catalog; `type` links to its entry. `detail` is human-readable and may change. Extension members appear only for the codes that document them; ignore members you do not recognize. 

  - Required fields: ` type `, ` title `, ` status `, ` code `, ` detail `

  - ` type `: type ` string `; format ` uri ` — `https://docs.beta.b3os.org/errors#<code>`.

    - example: ` "https://docs.beta.b3os.org/errors#invalid_request" `

  - ` title `: type ` string ` — Short summary of the problem type.

  - ` status `: type ` integer ` — The HTTP status code, repeated for convenience.

    - minimum: ` 400 `

    - maximum: ` 599 `

  - ` code `: type ` string ` — Stable machine-readable error code from the errors catalog.

    - pattern: ` "^[a-z][a-z0-9_]*$" `

  - ` detail `: type ` string ` — Explanation of this occurrence. Never contains secrets.

  - ` instance `: type ` string ` — The request ID (`req_…`) of the request that failed. Include it when you contact support.

    - example: ` "req_01m5t4yg394wegr3j4y01qb363" `

  - ` errors `: type ` array ` — Validation problems, one per field (`invalid_request` and the other codes that list `errors`).

    - ` array item `: type ` object ` — One validation problem.

      - Required fields: ` pointer `, ` detail `

      - ` pointer `: type ` string ` — Where the problem is: a JSON pointer into the request body (`/url`, `/steps/0/uses`), or `#query/<name>`, `#path/<name>` or `#header/<name>` for parameters. 

        - example: ` "/url" `

      - ` detail `: type ` string ` — What is wrong there.

        - example: ` "must be an absolute http or https URL" `

  - ` reason `: type ` string ` — Finer-grained cause for codes that document one (`unauthorized`, `forbidden`, `egress_denied`, `upstream_unreachable`, …).

  - ` required_scope `: type ` string ` — The scope that was missing (`forbidden` with `reason: scope`).

  - ` retry_after_s `: type ` integer ` — Same value as the `Retry-After` header, for clients that only read the body.

    - minimum: ` 0 `

  - ` limit `: type ` object ` — The limit an error refers to. IDs and current values are listed by `GET /v1/limits`.

    - Required fields: ` id `, ` limit `, ` unit `

    - ` id `: type ` string ` — Limit ID, such as `vision.scrape.rpm` or `sandboxes.concurrent`.

      - example: ` "vision.scrape.rpm" `

    - ` limit `: type ` number ` — The limit's value.

    - ` unit `: type ` string ` — What the limit counts, such as `requests`, `sandboxes`, `vcpu` or `MiB`.

    - ` window_s `: type ` integer ` — Window length in seconds for rate limits and quotas.

    - ` current `: type ` number ` — Current usage against the limit, when known.

  - ` current_status `: type ` string ` — The object's current status, for state conflicts such as `sandbox_not_running`.

  - ` upstream_status `: type ` integer ` — The HTTP status the upstream returned (`upstream_error`, `action_output_invalid`).

  - ` step `: type ` string ` — The failed step, as a step ID (routines), an index (`act`) or a path such as `beats/2/do/0` (render).

  - ` pack_error `: type ` object ` — The error a pack's error mapping chose (`upstream_error` from pack actions).

    - Required fields: ` code `, ` message `, ` retryable `

    - ` code `: type ` string `

    - ` message `: type ` string `

    - ` retryable `: type ` boolean `

Response header ` x-request-id ` — The request ID (`req_…`). It is the `instance` of any problem and the key for `GET /v1/requests/{request_id}`.

- ` value `: type ` string `

  - pattern: ` "^req_[0-9a-hjkmnp-tv-z]{26}$" `

Response header ` Server-Timing ` — Phase durations in milliseconds (W3C Server Timing); the handler's phases break the request down. For a
response whose body size is known, `total` runs from reading the request head to writing the response head.
Streaming responses (event streams, WebSockets, chunked bodies) carry no `total` here: they report their
final phases in the terminal event (`job.succeeded`, `job.failed`, `job.canceled`) or the final job. The
time from the first request byte to the last response byte is recorded in the node's metrics and request
log (`GET /v1/requests/{request_id}`). The edge prepends `edge_auth` and `edge_upstream`.


- ` value `: type ` string `

Example:

```json
{
  "type": "https://docs.beta.b3os.org/errors#invalid_request",
  "title": "Invalid request",
  "status": 400,
  "code": "invalid_request",
  "detail": "1 field failed validation",
  "instance": "req_01m5t4yg394wegr3j4y01qb363",
  "errors": [
    {
      "pointer": "/url",
      "detail": "must be an absolute http or https URL"
    }
  ]
}
```

### ` 401 ` — Missing, malformed, expired or revoked credentials (`unauthorized`).

Content type: ` application/problem+json `

- ` value `: type ` object ` — An RFC 9457 problem. `code` is stable and listed in the errors catalog; `type` links to its entry. `detail` is human-readable and may change. Extension members appear only for the codes that document them; ignore members you do not recognize. 

  - Required fields: ` type `, ` title `, ` status `, ` code `, ` detail `

  - ` type `: type ` string `; format ` uri ` — `https://docs.beta.b3os.org/errors#<code>`.

    - example: ` "https://docs.beta.b3os.org/errors#invalid_request" `

  - ` title `: type ` string ` — Short summary of the problem type.

  - ` status `: type ` integer ` — The HTTP status code, repeated for convenience.

    - minimum: ` 400 `

    - maximum: ` 599 `

  - ` code `: type ` string ` — Stable machine-readable error code from the errors catalog.

    - pattern: ` "^[a-z][a-z0-9_]*$" `

  - ` detail `: type ` string ` — Explanation of this occurrence. Never contains secrets.

  - ` instance `: type ` string ` — The request ID (`req_…`) of the request that failed. Include it when you contact support.

    - example: ` "req_01m5t4yg394wegr3j4y01qb363" `

  - ` errors `: type ` array ` — Validation problems, one per field (`invalid_request` and the other codes that list `errors`).

    - ` array item `: type ` object ` — One validation problem.

      - Required fields: ` pointer `, ` detail `

      - ` pointer `: type ` string ` — Where the problem is: a JSON pointer into the request body (`/url`, `/steps/0/uses`), or `#query/<name>`, `#path/<name>` or `#header/<name>` for parameters. 

        - example: ` "/url" `

      - ` detail `: type ` string ` — What is wrong there.

        - example: ` "must be an absolute http or https URL" `

  - ` reason `: type ` string ` — Finer-grained cause for codes that document one (`unauthorized`, `forbidden`, `egress_denied`, `upstream_unreachable`, …).

  - ` required_scope `: type ` string ` — The scope that was missing (`forbidden` with `reason: scope`).

  - ` retry_after_s `: type ` integer ` — Same value as the `Retry-After` header, for clients that only read the body.

    - minimum: ` 0 `

  - ` limit `: type ` object ` — The limit an error refers to. IDs and current values are listed by `GET /v1/limits`.

    - Required fields: ` id `, ` limit `, ` unit `

    - ` id `: type ` string ` — Limit ID, such as `vision.scrape.rpm` or `sandboxes.concurrent`.

      - example: ` "vision.scrape.rpm" `

    - ` limit `: type ` number ` — The limit's value.

    - ` unit `: type ` string ` — What the limit counts, such as `requests`, `sandboxes`, `vcpu` or `MiB`.

    - ` window_s `: type ` integer ` — Window length in seconds for rate limits and quotas.

    - ` current `: type ` number ` — Current usage against the limit, when known.

  - ` current_status `: type ` string ` — The object's current status, for state conflicts such as `sandbox_not_running`.

  - ` upstream_status `: type ` integer ` — The HTTP status the upstream returned (`upstream_error`, `action_output_invalid`).

  - ` step `: type ` string ` — The failed step, as a step ID (routines), an index (`act`) or a path such as `beats/2/do/0` (render).

  - ` pack_error `: type ` object ` — The error a pack's error mapping chose (`upstream_error` from pack actions).

    - Required fields: ` code `, ` message `, ` retryable `

    - ` code `: type ` string `

    - ` message `: type ` string `

    - ` retryable `: type ` boolean `

Response header ` x-request-id ` — The request ID (`req_…`). It is the `instance` of any problem and the key for `GET /v1/requests/{request_id}`.

- ` value `: type ` string `

  - pattern: ` "^req_[0-9a-hjkmnp-tv-z]{26}$" `

Response header ` Server-Timing ` — Phase durations in milliseconds (W3C Server Timing); the handler's phases break the request down. For a
response whose body size is known, `total` runs from reading the request head to writing the response head.
Streaming responses (event streams, WebSockets, chunked bodies) carry no `total` here: they report their
final phases in the terminal event (`job.succeeded`, `job.failed`, `job.canceled`) or the final job. The
time from the first request byte to the last response byte is recorded in the node's metrics and request
log (`GET /v1/requests/{request_id}`). The edge prepends `edge_auth` and `edge_upstream`.


- ` value `: type ` string `

Example:

```json
{
  "type": "https://docs.beta.b3os.org/errors#unauthorized",
  "title": "Unauthorized",
  "status": 401,
  "code": "unauthorized",
  "detail": "API key checksum does not match; check that the whole key was copied",
  "instance": "req_01m5t4yg394wegr3j4y01qb363",
  "reason": "malformed"
}
```

### ` 403 ` — Authenticated but not allowed (`forbidden`, `egress_denied`).

Content type: ` application/problem+json `

- ` value `: type ` object ` — An RFC 9457 problem. `code` is stable and listed in the errors catalog; `type` links to its entry. `detail` is human-readable and may change. Extension members appear only for the codes that document them; ignore members you do not recognize. 

  - Required fields: ` type `, ` title `, ` status `, ` code `, ` detail `

  - ` type `: type ` string `; format ` uri ` — `https://docs.beta.b3os.org/errors#<code>`.

    - example: ` "https://docs.beta.b3os.org/errors#invalid_request" `

  - ` title `: type ` string ` — Short summary of the problem type.

  - ` status `: type ` integer ` — The HTTP status code, repeated for convenience.

    - minimum: ` 400 `

    - maximum: ` 599 `

  - ` code `: type ` string ` — Stable machine-readable error code from the errors catalog.

    - pattern: ` "^[a-z][a-z0-9_]*$" `

  - ` detail `: type ` string ` — Explanation of this occurrence. Never contains secrets.

  - ` instance `: type ` string ` — The request ID (`req_…`) of the request that failed. Include it when you contact support.

    - example: ` "req_01m5t4yg394wegr3j4y01qb363" `

  - ` errors `: type ` array ` — Validation problems, one per field (`invalid_request` and the other codes that list `errors`).

    - ` array item `: type ` object ` — One validation problem.

      - Required fields: ` pointer `, ` detail `

      - ` pointer `: type ` string ` — Where the problem is: a JSON pointer into the request body (`/url`, `/steps/0/uses`), or `#query/<name>`, `#path/<name>` or `#header/<name>` for parameters. 

        - example: ` "/url" `

      - ` detail `: type ` string ` — What is wrong there.

        - example: ` "must be an absolute http or https URL" `

  - ` reason `: type ` string ` — Finer-grained cause for codes that document one (`unauthorized`, `forbidden`, `egress_denied`, `upstream_unreachable`, …).

  - ` required_scope `: type ` string ` — The scope that was missing (`forbidden` with `reason: scope`).

  - ` retry_after_s `: type ` integer ` — Same value as the `Retry-After` header, for clients that only read the body.

    - minimum: ` 0 `

  - ` limit `: type ` object ` — The limit an error refers to. IDs and current values are listed by `GET /v1/limits`.

    - Required fields: ` id `, ` limit `, ` unit `

    - ` id `: type ` string ` — Limit ID, such as `vision.scrape.rpm` or `sandboxes.concurrent`.

      - example: ` "vision.scrape.rpm" `

    - ` limit `: type ` number ` — The limit's value.

    - ` unit `: type ` string ` — What the limit counts, such as `requests`, `sandboxes`, `vcpu` or `MiB`.

    - ` window_s `: type ` integer ` — Window length in seconds for rate limits and quotas.

    - ` current `: type ` number ` — Current usage against the limit, when known.

  - ` current_status `: type ` string ` — The object's current status, for state conflicts such as `sandbox_not_running`.

  - ` upstream_status `: type ` integer ` — The HTTP status the upstream returned (`upstream_error`, `action_output_invalid`).

  - ` step `: type ` string ` — The failed step, as a step ID (routines), an index (`act`) or a path such as `beats/2/do/0` (render).

  - ` pack_error `: type ` object ` — The error a pack's error mapping chose (`upstream_error` from pack actions).

    - Required fields: ` code `, ` message `, ` retryable `

    - ` code `: type ` string `

    - ` message `: type ` string `

    - ` retryable `: type ` boolean `

Response header ` x-request-id ` — The request ID (`req_…`). It is the `instance` of any problem and the key for `GET /v1/requests/{request_id}`.

- ` value `: type ` string `

  - pattern: ` "^req_[0-9a-hjkmnp-tv-z]{26}$" `

Response header ` Server-Timing ` — Phase durations in milliseconds (W3C Server Timing); the handler's phases break the request down. For a
response whose body size is known, `total` runs from reading the request head to writing the response head.
Streaming responses (event streams, WebSockets, chunked bodies) carry no `total` here: they report their
final phases in the terminal event (`job.succeeded`, `job.failed`, `job.canceled`) or the final job. The
time from the first request byte to the last response byte is recorded in the node's metrics and request
log (`GET /v1/requests/{request_id}`). The edge prepends `edge_auth` and `edge_upstream`.


- ` value `: type ` string `

Example:

```json
{
  "type": "https://docs.beta.b3os.org/errors#forbidden",
  "title": "Forbidden",
  "status": 403,
  "code": "forbidden",
  "detail": "This key lacks the scope sandboxes:write",
  "instance": "req_01m5t4yg394wegr3j4y01qb363",
  "reason": "scope",
  "required_scope": "sandboxes:write"
}
```

### ` 404 ` — No such sandbox in this project (`sandbox_not_found`).

Content type: ` application/problem+json `

- ` value `: type ` object ` — An RFC 9457 problem. `code` is stable and listed in the errors catalog; `type` links to its entry. `detail` is human-readable and may change. Extension members appear only for the codes that document them; ignore members you do not recognize. 

  - Required fields: ` type `, ` title `, ` status `, ` code `, ` detail `

  - ` type `: type ` string `; format ` uri ` — `https://docs.beta.b3os.org/errors#<code>`.

    - example: ` "https://docs.beta.b3os.org/errors#invalid_request" `

  - ` title `: type ` string ` — Short summary of the problem type.

  - ` status `: type ` integer ` — The HTTP status code, repeated for convenience.

    - minimum: ` 400 `

    - maximum: ` 599 `

  - ` code `: type ` string ` — Stable machine-readable error code from the errors catalog.

    - pattern: ` "^[a-z][a-z0-9_]*$" `

  - ` detail `: type ` string ` — Explanation of this occurrence. Never contains secrets.

  - ` instance `: type ` string ` — The request ID (`req_…`) of the request that failed. Include it when you contact support.

    - example: ` "req_01m5t4yg394wegr3j4y01qb363" `

  - ` errors `: type ` array ` — Validation problems, one per field (`invalid_request` and the other codes that list `errors`).

    - ` array item `: type ` object ` — One validation problem.

      - Required fields: ` pointer `, ` detail `

      - ` pointer `: type ` string ` — Where the problem is: a JSON pointer into the request body (`/url`, `/steps/0/uses`), or `#query/<name>`, `#path/<name>` or `#header/<name>` for parameters. 

        - example: ` "/url" `

      - ` detail `: type ` string ` — What is wrong there.

        - example: ` "must be an absolute http or https URL" `

  - ` reason `: type ` string ` — Finer-grained cause for codes that document one (`unauthorized`, `forbidden`, `egress_denied`, `upstream_unreachable`, …).

  - ` required_scope `: type ` string ` — The scope that was missing (`forbidden` with `reason: scope`).

  - ` retry_after_s `: type ` integer ` — Same value as the `Retry-After` header, for clients that only read the body.

    - minimum: ` 0 `

  - ` limit `: type ` object ` — The limit an error refers to. IDs and current values are listed by `GET /v1/limits`.

    - Required fields: ` id `, ` limit `, ` unit `

    - ` id `: type ` string ` — Limit ID, such as `vision.scrape.rpm` or `sandboxes.concurrent`.

      - example: ` "vision.scrape.rpm" `

    - ` limit `: type ` number ` — The limit's value.

    - ` unit `: type ` string ` — What the limit counts, such as `requests`, `sandboxes`, `vcpu` or `MiB`.

    - ` window_s `: type ` integer ` — Window length in seconds for rate limits and quotas.

    - ` current `: type ` number ` — Current usage against the limit, when known.

  - ` current_status `: type ` string ` — The object's current status, for state conflicts such as `sandbox_not_running`.

  - ` upstream_status `: type ` integer ` — The HTTP status the upstream returned (`upstream_error`, `action_output_invalid`).

  - ` step `: type ` string ` — The failed step, as a step ID (routines), an index (`act`) or a path such as `beats/2/do/0` (render).

  - ` pack_error `: type ` object ` — The error a pack's error mapping chose (`upstream_error` from pack actions).

    - Required fields: ` code `, ` message `, ` retryable `

    - ` code `: type ` string `

    - ` message `: type ` string `

    - ` retryable `: type ` boolean `

Response header ` x-request-id ` — The request ID (`req_…`). It is the `instance` of any problem and the key for `GET /v1/requests/{request_id}`.

- ` value `: type ` string `

  - pattern: ` "^req_[0-9a-hjkmnp-tv-z]{26}$" `

Response header ` Server-Timing ` — Phase durations in milliseconds (W3C Server Timing); the handler's phases break the request down. For a
response whose body size is known, `total` runs from reading the request head to writing the response head.
Streaming responses (event streams, WebSockets, chunked bodies) carry no `total` here: they report their
final phases in the terminal event (`job.succeeded`, `job.failed`, `job.canceled`) or the final job. The
time from the first request byte to the last response byte is recorded in the node's metrics and request
log (`GET /v1/requests/{request_id}`). The edge prepends `edge_auth` and `edge_upstream`.


- ` value `: type ` string `

Example:

```json
{
  "type": "https://docs.beta.b3os.org/errors#sandbox_not_found",
  "title": "Sandbox not found",
  "status": 404,
  "code": "sandbox_not_found",
  "detail": "No sandbox sbx_01m5t68q1b590rj801nbzsqzkk in this project",
  "instance": "req_01m5t4yg394wegr3j4y01qb363"
}
```

### ` 409 ` — The sandbox is paused or stopped (`sandbox_not_running`).

Content type: ` application/problem+json `

- ` value `: type ` object ` — An RFC 9457 problem. `code` is stable and listed in the errors catalog; `type` links to its entry. `detail` is human-readable and may change. Extension members appear only for the codes that document them; ignore members you do not recognize. 

  - Required fields: ` type `, ` title `, ` status `, ` code `, ` detail `

  - ` type `: type ` string `; format ` uri ` — `https://docs.beta.b3os.org/errors#<code>`.

    - example: ` "https://docs.beta.b3os.org/errors#invalid_request" `

  - ` title `: type ` string ` — Short summary of the problem type.

  - ` status `: type ` integer ` — The HTTP status code, repeated for convenience.

    - minimum: ` 400 `

    - maximum: ` 599 `

  - ` code `: type ` string ` — Stable machine-readable error code from the errors catalog.

    - pattern: ` "^[a-z][a-z0-9_]*$" `

  - ` detail `: type ` string ` — Explanation of this occurrence. Never contains secrets.

  - ` instance `: type ` string ` — The request ID (`req_…`) of the request that failed. Include it when you contact support.

    - example: ` "req_01m5t4yg394wegr3j4y01qb363" `

  - ` errors `: type ` array ` — Validation problems, one per field (`invalid_request` and the other codes that list `errors`).

    - ` array item `: type ` object ` — One validation problem.

      - Required fields: ` pointer `, ` detail `

      - ` pointer `: type ` string ` — Where the problem is: a JSON pointer into the request body (`/url`, `/steps/0/uses`), or `#query/<name>`, `#path/<name>` or `#header/<name>` for parameters. 

        - example: ` "/url" `

      - ` detail `: type ` string ` — What is wrong there.

        - example: ` "must be an absolute http or https URL" `

  - ` reason `: type ` string ` — Finer-grained cause for codes that document one (`unauthorized`, `forbidden`, `egress_denied`, `upstream_unreachable`, …).

  - ` required_scope `: type ` string ` — The scope that was missing (`forbidden` with `reason: scope`).

  - ` retry_after_s `: type ` integer ` — Same value as the `Retry-After` header, for clients that only read the body.

    - minimum: ` 0 `

  - ` limit `: type ` object ` — The limit an error refers to. IDs and current values are listed by `GET /v1/limits`.

    - Required fields: ` id `, ` limit `, ` unit `

    - ` id `: type ` string ` — Limit ID, such as `vision.scrape.rpm` or `sandboxes.concurrent`.

      - example: ` "vision.scrape.rpm" `

    - ` limit `: type ` number ` — The limit's value.

    - ` unit `: type ` string ` — What the limit counts, such as `requests`, `sandboxes`, `vcpu` or `MiB`.

    - ` window_s `: type ` integer ` — Window length in seconds for rate limits and quotas.

    - ` current `: type ` number ` — Current usage against the limit, when known.

  - ` current_status `: type ` string ` — The object's current status, for state conflicts such as `sandbox_not_running`.

  - ` upstream_status `: type ` integer ` — The HTTP status the upstream returned (`upstream_error`, `action_output_invalid`).

  - ` step `: type ` string ` — The failed step, as a step ID (routines), an index (`act`) or a path such as `beats/2/do/0` (render).

  - ` pack_error `: type ` object ` — The error a pack's error mapping chose (`upstream_error` from pack actions).

    - Required fields: ` code `, ` message `, ` retryable `

    - ` code `: type ` string `

    - ` message `: type ` string `

    - ` retryable `: type ` boolean `

Response header ` x-request-id ` — The request ID (`req_…`). It is the `instance` of any problem and the key for `GET /v1/requests/{request_id}`.

- ` value `: type ` string `

  - pattern: ` "^req_[0-9a-hjkmnp-tv-z]{26}$" `

Response header ` Server-Timing ` — Phase durations in milliseconds (W3C Server Timing); the handler's phases break the request down. For a
response whose body size is known, `total` runs from reading the request head to writing the response head.
Streaming responses (event streams, WebSockets, chunked bodies) carry no `total` here: they report their
final phases in the terminal event (`job.succeeded`, `job.failed`, `job.canceled`) or the final job. The
time from the first request byte to the last response byte is recorded in the node's metrics and request
log (`GET /v1/requests/{request_id}`). The edge prepends `edge_auth` and `edge_upstream`.


- ` value `: type ` string `

Example:

```json
{
  "type": "https://docs.beta.b3os.org/errors#sandbox_not_running",
  "title": "Sandbox not running",
  "status": 409,
  "code": "sandbox_not_running",
  "detail": "sbx_01m5t68q1b590rj801nbzsqzkk is paused; resume it first",
  "instance": "req_01m5t4yg394wegr3j4y01qb363",
  "current_status": "paused"
}
```

### ` 413 ` — The request body exceeds this operation's limit.

Content type: ` application/problem+json `

- ` value `: type ` object ` — An RFC 9457 problem. `code` is stable and listed in the errors catalog; `type` links to its entry. `detail` is human-readable and may change. Extension members appear only for the codes that document them; ignore members you do not recognize. 

  - Required fields: ` type `, ` title `, ` status `, ` code `, ` detail `

  - ` type `: type ` string `; format ` uri ` — `https://docs.beta.b3os.org/errors#<code>`.

    - example: ` "https://docs.beta.b3os.org/errors#invalid_request" `

  - ` title `: type ` string ` — Short summary of the problem type.

  - ` status `: type ` integer ` — The HTTP status code, repeated for convenience.

    - minimum: ` 400 `

    - maximum: ` 599 `

  - ` code `: type ` string ` — Stable machine-readable error code from the errors catalog.

    - pattern: ` "^[a-z][a-z0-9_]*$" `

  - ` detail `: type ` string ` — Explanation of this occurrence. Never contains secrets.

  - ` instance `: type ` string ` — The request ID (`req_…`) of the request that failed. Include it when you contact support.

    - example: ` "req_01m5t4yg394wegr3j4y01qb363" `

  - ` errors `: type ` array ` — Validation problems, one per field (`invalid_request` and the other codes that list `errors`).

    - ` array item `: type ` object ` — One validation problem.

      - Required fields: ` pointer `, ` detail `

      - ` pointer `: type ` string ` — Where the problem is: a JSON pointer into the request body (`/url`, `/steps/0/uses`), or `#query/<name>`, `#path/<name>` or `#header/<name>` for parameters. 

        - example: ` "/url" `

      - ` detail `: type ` string ` — What is wrong there.

        - example: ` "must be an absolute http or https URL" `

  - ` reason `: type ` string ` — Finer-grained cause for codes that document one (`unauthorized`, `forbidden`, `egress_denied`, `upstream_unreachable`, …).

  - ` required_scope `: type ` string ` — The scope that was missing (`forbidden` with `reason: scope`).

  - ` retry_after_s `: type ` integer ` — Same value as the `Retry-After` header, for clients that only read the body.

    - minimum: ` 0 `

  - ` limit `: type ` object ` — The limit an error refers to. IDs and current values are listed by `GET /v1/limits`.

    - Required fields: ` id `, ` limit `, ` unit `

    - ` id `: type ` string ` — Limit ID, such as `vision.scrape.rpm` or `sandboxes.concurrent`.

      - example: ` "vision.scrape.rpm" `

    - ` limit `: type ` number ` — The limit's value.

    - ` unit `: type ` string ` — What the limit counts, such as `requests`, `sandboxes`, `vcpu` or `MiB`.

    - ` window_s `: type ` integer ` — Window length in seconds for rate limits and quotas.

    - ` current `: type ` number ` — Current usage against the limit, when known.

  - ` current_status `: type ` string ` — The object's current status, for state conflicts such as `sandbox_not_running`.

  - ` upstream_status `: type ` integer ` — The HTTP status the upstream returned (`upstream_error`, `action_output_invalid`).

  - ` step `: type ` string ` — The failed step, as a step ID (routines), an index (`act`) or a path such as `beats/2/do/0` (render).

  - ` pack_error `: type ` object ` — The error a pack's error mapping chose (`upstream_error` from pack actions).

    - Required fields: ` code `, ` message `, ` retryable `

    - ` code `: type ` string `

    - ` message `: type ` string `

    - ` retryable `: type ` boolean `

Response header ` x-request-id ` — The request ID (`req_…`). It is the `instance` of any problem and the key for `GET /v1/requests/{request_id}`.

- ` value `: type ` string `

  - pattern: ` "^req_[0-9a-hjkmnp-tv-z]{26}$" `

Response header ` Server-Timing ` — Phase durations in milliseconds (W3C Server Timing); the handler's phases break the request down. For a
response whose body size is known, `total` runs from reading the request head to writing the response head.
Streaming responses (event streams, WebSockets, chunked bodies) carry no `total` here: they report their
final phases in the terminal event (`job.succeeded`, `job.failed`, `job.canceled`) or the final job. The
time from the first request byte to the last response byte is recorded in the node's metrics and request
log (`GET /v1/requests/{request_id}`). The edge prepends `edge_auth` and `edge_upstream`.


- ` value `: type ` string `

Example:

```json
{
  "type": "https://docs.beta.b3os.org/errors#payload_too_large",
  "title": "Payload too large",
  "status": 413,
  "code": "payload_too_large",
  "detail": "Request body is 1572864 bytes; this operation accepts at most 1048576",
  "instance": "req_01m5t4yg394wegr3j4y01qb363"
}
```

### ` 415 ` — The Content-Type is not accepted by this operation.

Content type: ` application/problem+json `

- ` value `: type ` object ` — An RFC 9457 problem. `code` is stable and listed in the errors catalog; `type` links to its entry. `detail` is human-readable and may change. Extension members appear only for the codes that document them; ignore members you do not recognize. 

  - Required fields: ` type `, ` title `, ` status `, ` code `, ` detail `

  - ` type `: type ` string `; format ` uri ` — `https://docs.beta.b3os.org/errors#<code>`.

    - example: ` "https://docs.beta.b3os.org/errors#invalid_request" `

  - ` title `: type ` string ` — Short summary of the problem type.

  - ` status `: type ` integer ` — The HTTP status code, repeated for convenience.

    - minimum: ` 400 `

    - maximum: ` 599 `

  - ` code `: type ` string ` — Stable machine-readable error code from the errors catalog.

    - pattern: ` "^[a-z][a-z0-9_]*$" `

  - ` detail `: type ` string ` — Explanation of this occurrence. Never contains secrets.

  - ` instance `: type ` string ` — The request ID (`req_…`) of the request that failed. Include it when you contact support.

    - example: ` "req_01m5t4yg394wegr3j4y01qb363" `

  - ` errors `: type ` array ` — Validation problems, one per field (`invalid_request` and the other codes that list `errors`).

    - ` array item `: type ` object ` — One validation problem.

      - Required fields: ` pointer `, ` detail `

      - ` pointer `: type ` string ` — Where the problem is: a JSON pointer into the request body (`/url`, `/steps/0/uses`), or `#query/<name>`, `#path/<name>` or `#header/<name>` for parameters. 

        - example: ` "/url" `

      - ` detail `: type ` string ` — What is wrong there.

        - example: ` "must be an absolute http or https URL" `

  - ` reason `: type ` string ` — Finer-grained cause for codes that document one (`unauthorized`, `forbidden`, `egress_denied`, `upstream_unreachable`, …).

  - ` required_scope `: type ` string ` — The scope that was missing (`forbidden` with `reason: scope`).

  - ` retry_after_s `: type ` integer ` — Same value as the `Retry-After` header, for clients that only read the body.

    - minimum: ` 0 `

  - ` limit `: type ` object ` — The limit an error refers to. IDs and current values are listed by `GET /v1/limits`.

    - Required fields: ` id `, ` limit `, ` unit `

    - ` id `: type ` string ` — Limit ID, such as `vision.scrape.rpm` or `sandboxes.concurrent`.

      - example: ` "vision.scrape.rpm" `

    - ` limit `: type ` number ` — The limit's value.

    - ` unit `: type ` string ` — What the limit counts, such as `requests`, `sandboxes`, `vcpu` or `MiB`.

    - ` window_s `: type ` integer ` — Window length in seconds for rate limits and quotas.

    - ` current `: type ` number ` — Current usage against the limit, when known.

  - ` current_status `: type ` string ` — The object's current status, for state conflicts such as `sandbox_not_running`.

  - ` upstream_status `: type ` integer ` — The HTTP status the upstream returned (`upstream_error`, `action_output_invalid`).

  - ` step `: type ` string ` — The failed step, as a step ID (routines), an index (`act`) or a path such as `beats/2/do/0` (render).

  - ` pack_error `: type ` object ` — The error a pack's error mapping chose (`upstream_error` from pack actions).

    - Required fields: ` code `, ` message `, ` retryable `

    - ` code `: type ` string `

    - ` message `: type ` string `

    - ` retryable `: type ` boolean `

Response header ` x-request-id ` — The request ID (`req_…`). It is the `instance` of any problem and the key for `GET /v1/requests/{request_id}`.

- ` value `: type ` string `

  - pattern: ` "^req_[0-9a-hjkmnp-tv-z]{26}$" `

Response header ` Server-Timing ` — Phase durations in milliseconds (W3C Server Timing); the handler's phases break the request down. For a
response whose body size is known, `total` runs from reading the request head to writing the response head.
Streaming responses (event streams, WebSockets, chunked bodies) carry no `total` here: they report their
final phases in the terminal event (`job.succeeded`, `job.failed`, `job.canceled`) or the final job. The
time from the first request byte to the last response byte is recorded in the node's metrics and request
log (`GET /v1/requests/{request_id}`). The edge prepends `edge_auth` and `edge_upstream`.


- ` value `: type ` string `

Example:

```json
{
  "type": "https://docs.beta.b3os.org/errors#unsupported_media_type",
  "title": "Unsupported media type",
  "status": 415,
  "code": "unsupported_media_type",
  "detail": "Expected Content-Type application/json",
  "instance": "req_01m5t4yg394wegr3j4y01qb363"
}
```

### ` 422 ` — The organization's snapshots on this node reached a limit (`limit_exceeded`).

Content type: ` application/problem+json `

- ` value `: type ` object ` — An RFC 9457 problem. `code` is stable and listed in the errors catalog; `type` links to its entry. `detail` is human-readable and may change. Extension members appear only for the codes that document them; ignore members you do not recognize. 

  - Required fields: ` type `, ` title `, ` status `, ` code `, ` detail `

  - ` type `: type ` string `; format ` uri ` — `https://docs.beta.b3os.org/errors#<code>`.

    - example: ` "https://docs.beta.b3os.org/errors#invalid_request" `

  - ` title `: type ` string ` — Short summary of the problem type.

  - ` status `: type ` integer ` — The HTTP status code, repeated for convenience.

    - minimum: ` 400 `

    - maximum: ` 599 `

  - ` code `: type ` string ` — Stable machine-readable error code from the errors catalog.

    - pattern: ` "^[a-z][a-z0-9_]*$" `

  - ` detail `: type ` string ` — Explanation of this occurrence. Never contains secrets.

  - ` instance `: type ` string ` — The request ID (`req_…`) of the request that failed. Include it when you contact support.

    - example: ` "req_01m5t4yg394wegr3j4y01qb363" `

  - ` errors `: type ` array ` — Validation problems, one per field (`invalid_request` and the other codes that list `errors`).

    - ` array item `: type ` object ` — One validation problem.

      - Required fields: ` pointer `, ` detail `

      - ` pointer `: type ` string ` — Where the problem is: a JSON pointer into the request body (`/url`, `/steps/0/uses`), or `#query/<name>`, `#path/<name>` or `#header/<name>` for parameters. 

        - example: ` "/url" `

      - ` detail `: type ` string ` — What is wrong there.

        - example: ` "must be an absolute http or https URL" `

  - ` reason `: type ` string ` — Finer-grained cause for codes that document one (`unauthorized`, `forbidden`, `egress_denied`, `upstream_unreachable`, …).

  - ` required_scope `: type ` string ` — The scope that was missing (`forbidden` with `reason: scope`).

  - ` retry_after_s `: type ` integer ` — Same value as the `Retry-After` header, for clients that only read the body.

    - minimum: ` 0 `

  - ` limit `: type ` object ` — The limit an error refers to. IDs and current values are listed by `GET /v1/limits`.

    - Required fields: ` id `, ` limit `, ` unit `

    - ` id `: type ` string ` — Limit ID, such as `vision.scrape.rpm` or `sandboxes.concurrent`.

      - example: ` "vision.scrape.rpm" `

    - ` limit `: type ` number ` — The limit's value.

    - ` unit `: type ` string ` — What the limit counts, such as `requests`, `sandboxes`, `vcpu` or `MiB`.

    - ` window_s `: type ` integer ` — Window length in seconds for rate limits and quotas.

    - ` current `: type ` number ` — Current usage against the limit, when known.

  - ` current_status `: type ` string ` — The object's current status, for state conflicts such as `sandbox_not_running`.

  - ` upstream_status `: type ` integer ` — The HTTP status the upstream returned (`upstream_error`, `action_output_invalid`).

  - ` step `: type ` string ` — The failed step, as a step ID (routines), an index (`act`) or a path such as `beats/2/do/0` (render).

  - ` pack_error `: type ` object ` — The error a pack's error mapping chose (`upstream_error` from pack actions).

    - Required fields: ` code `, ` message `, ` retryable `

    - ` code `: type ` string `

    - ` message `: type ` string `

    - ` retryable `: type ` boolean `

Response header ` x-request-id ` — The request ID (`req_…`). It is the `instance` of any problem and the key for `GET /v1/requests/{request_id}`.

- ` value `: type ` string `

  - pattern: ` "^req_[0-9a-hjkmnp-tv-z]{26}$" `

Response header ` Server-Timing ` — Phase durations in milliseconds (W3C Server Timing); the handler's phases break the request down. For a
response whose body size is known, `total` runs from reading the request head to writing the response head.
Streaming responses (event streams, WebSockets, chunked bodies) carry no `total` here: they report their
final phases in the terminal event (`job.succeeded`, `job.failed`, `job.canceled`) or the final job. The
time from the first request byte to the last response byte is recorded in the node's metrics and request
log (`GET /v1/requests/{request_id}`). The edge prepends `edge_auth` and `edge_upstream`.


- ` value `: type ` string `

Example:

```json
{
  "type": "https://docs.beta.b3os.org/errors#limit_exceeded",
  "title": "Limit exceeded",
  "status": 422,
  "code": "limit_exceeded",
  "detail": "This organization keeps 20 snapshots on this node (the limit is 20); delete some first",
  "instance": "req_01m5t4yg394wegr3j4y01qb363",
  "limit": {
    "id": "sandboxes.snapshots_max",
    "limit": 20,
    "unit": "snapshots"
  }
}
```

### ` 429 ` — A rate, concurrency or quota limit applies (`rate_limited`, `concurrency_limited`, `quota_exceeded`).

Content type: ` application/problem+json `

- ` value `: type ` object ` — An RFC 9457 problem. `code` is stable and listed in the errors catalog; `type` links to its entry. `detail` is human-readable and may change. Extension members appear only for the codes that document them; ignore members you do not recognize. 

  - Required fields: ` type `, ` title `, ` status `, ` code `, ` detail `

  - ` type `: type ` string `; format ` uri ` — `https://docs.beta.b3os.org/errors#<code>`.

    - example: ` "https://docs.beta.b3os.org/errors#invalid_request" `

  - ` title `: type ` string ` — Short summary of the problem type.

  - ` status `: type ` integer ` — The HTTP status code, repeated for convenience.

    - minimum: ` 400 `

    - maximum: ` 599 `

  - ` code `: type ` string ` — Stable machine-readable error code from the errors catalog.

    - pattern: ` "^[a-z][a-z0-9_]*$" `

  - ` detail `: type ` string ` — Explanation of this occurrence. Never contains secrets.

  - ` instance `: type ` string ` — The request ID (`req_…`) of the request that failed. Include it when you contact support.

    - example: ` "req_01m5t4yg394wegr3j4y01qb363" `

  - ` errors `: type ` array ` — Validation problems, one per field (`invalid_request` and the other codes that list `errors`).

    - ` array item `: type ` object ` — One validation problem.

      - Required fields: ` pointer `, ` detail `

      - ` pointer `: type ` string ` — Where the problem is: a JSON pointer into the request body (`/url`, `/steps/0/uses`), or `#query/<name>`, `#path/<name>` or `#header/<name>` for parameters. 

        - example: ` "/url" `

      - ` detail `: type ` string ` — What is wrong there.

        - example: ` "must be an absolute http or https URL" `

  - ` reason `: type ` string ` — Finer-grained cause for codes that document one (`unauthorized`, `forbidden`, `egress_denied`, `upstream_unreachable`, …).

  - ` required_scope `: type ` string ` — The scope that was missing (`forbidden` with `reason: scope`).

  - ` retry_after_s `: type ` integer ` — Same value as the `Retry-After` header, for clients that only read the body.

    - minimum: ` 0 `

  - ` limit `: type ` object ` — The limit an error refers to. IDs and current values are listed by `GET /v1/limits`.

    - Required fields: ` id `, ` limit `, ` unit `

    - ` id `: type ` string ` — Limit ID, such as `vision.scrape.rpm` or `sandboxes.concurrent`.

      - example: ` "vision.scrape.rpm" `

    - ` limit `: type ` number ` — The limit's value.

    - ` unit `: type ` string ` — What the limit counts, such as `requests`, `sandboxes`, `vcpu` or `MiB`.

    - ` window_s `: type ` integer ` — Window length in seconds for rate limits and quotas.

    - ` current `: type ` number ` — Current usage against the limit, when known.

  - ` current_status `: type ` string ` — The object's current status, for state conflicts such as `sandbox_not_running`.

  - ` upstream_status `: type ` integer ` — The HTTP status the upstream returned (`upstream_error`, `action_output_invalid`).

  - ` step `: type ` string ` — The failed step, as a step ID (routines), an index (`act`) or a path such as `beats/2/do/0` (render).

  - ` pack_error `: type ` object ` — The error a pack's error mapping chose (`upstream_error` from pack actions).

    - Required fields: ` code `, ` message `, ` retryable `

    - ` code `: type ` string `

    - ` message `: type ` string `

    - ` retryable `: type ` boolean `

Response header ` x-request-id ` — The request ID (`req_…`). It is the `instance` of any problem and the key for `GET /v1/requests/{request_id}`.

- ` value `: type ` string `

  - pattern: ` "^req_[0-9a-hjkmnp-tv-z]{26}$" `

Response header ` Server-Timing ` — Phase durations in milliseconds (W3C Server Timing); the handler's phases break the request down. For a
response whose body size is known, `total` runs from reading the request head to writing the response head.
Streaming responses (event streams, WebSockets, chunked bodies) carry no `total` here: they report their
final phases in the terminal event (`job.succeeded`, `job.failed`, `job.canceled`) or the final job. The
time from the first request byte to the last response byte is recorded in the node's metrics and request
log (`GET /v1/requests/{request_id}`). The edge prepends `edge_auth` and `edge_upstream`.


- ` value `: type ` string `

Response header ` Retry-After ` — Seconds to wait before retrying or polling again.

- ` value `: type ` integer `

  - minimum: ` 0 `

Response header ` RateLimit-Limit ` — Requests allowed in the current window for the limit that applies to this operation.

- ` value `: type ` integer `

Response header ` RateLimit-Remaining ` — Requests left in the current window.

- ` value `: type ` integer `

Response header ` RateLimit-Reset ` — Seconds until the current window resets.

- ` value `: type ` integer `

Response header ` RateLimit-Policy ` — The applied policy as `<limit>;w=<window seconds>;name="<limit id>"` (limit IDs are listed by `GET /v1/limits`).

- ` value `: type ` string `

Example:

```json
{
  "type": "https://docs.beta.b3os.org/errors#rate_limited",
  "title": "Rate limited",
  "status": 429,
  "code": "rate_limited",
  "detail": "60 scrapes per minute allowed; retry in 12 seconds",
  "instance": "req_01m5t4yg394wegr3j4y01qb363",
  "retry_after_s": 12,
  "limit": {
    "id": "vision.scrape.rpm",
    "limit": 60,
    "unit": "requests",
    "window_s": 60,
    "current": 60
  }
}
```

### ` 500 ` — Something failed inside B3OS (`internal`). Retry with backoff.

Content type: ` application/problem+json `

- ` value `: type ` object ` — An RFC 9457 problem. `code` is stable and listed in the errors catalog; `type` links to its entry. `detail` is human-readable and may change. Extension members appear only for the codes that document them; ignore members you do not recognize. 

  - Required fields: ` type `, ` title `, ` status `, ` code `, ` detail `

  - ` type `: type ` string `; format ` uri ` — `https://docs.beta.b3os.org/errors#<code>`.

    - example: ` "https://docs.beta.b3os.org/errors#invalid_request" `

  - ` title `: type ` string ` — Short summary of the problem type.

  - ` status `: type ` integer ` — The HTTP status code, repeated for convenience.

    - minimum: ` 400 `

    - maximum: ` 599 `

  - ` code `: type ` string ` — Stable machine-readable error code from the errors catalog.

    - pattern: ` "^[a-z][a-z0-9_]*$" `

  - ` detail `: type ` string ` — Explanation of this occurrence. Never contains secrets.

  - ` instance `: type ` string ` — The request ID (`req_…`) of the request that failed. Include it when you contact support.

    - example: ` "req_01m5t4yg394wegr3j4y01qb363" `

  - ` errors `: type ` array ` — Validation problems, one per field (`invalid_request` and the other codes that list `errors`).

    - ` array item `: type ` object ` — One validation problem.

      - Required fields: ` pointer `, ` detail `

      - ` pointer `: type ` string ` — Where the problem is: a JSON pointer into the request body (`/url`, `/steps/0/uses`), or `#query/<name>`, `#path/<name>` or `#header/<name>` for parameters. 

        - example: ` "/url" `

      - ` detail `: type ` string ` — What is wrong there.

        - example: ` "must be an absolute http or https URL" `

  - ` reason `: type ` string ` — Finer-grained cause for codes that document one (`unauthorized`, `forbidden`, `egress_denied`, `upstream_unreachable`, …).

  - ` required_scope `: type ` string ` — The scope that was missing (`forbidden` with `reason: scope`).

  - ` retry_after_s `: type ` integer ` — Same value as the `Retry-After` header, for clients that only read the body.

    - minimum: ` 0 `

  - ` limit `: type ` object ` — The limit an error refers to. IDs and current values are listed by `GET /v1/limits`.

    - Required fields: ` id `, ` limit `, ` unit `

    - ` id `: type ` string ` — Limit ID, such as `vision.scrape.rpm` or `sandboxes.concurrent`.

      - example: ` "vision.scrape.rpm" `

    - ` limit `: type ` number ` — The limit's value.

    - ` unit `: type ` string ` — What the limit counts, such as `requests`, `sandboxes`, `vcpu` or `MiB`.

    - ` window_s `: type ` integer ` — Window length in seconds for rate limits and quotas.

    - ` current `: type ` number ` — Current usage against the limit, when known.

  - ` current_status `: type ` string ` — The object's current status, for state conflicts such as `sandbox_not_running`.

  - ` upstream_status `: type ` integer ` — The HTTP status the upstream returned (`upstream_error`, `action_output_invalid`).

  - ` step `: type ` string ` — The failed step, as a step ID (routines), an index (`act`) or a path such as `beats/2/do/0` (render).

  - ` pack_error `: type ` object ` — The error a pack's error mapping chose (`upstream_error` from pack actions).

    - Required fields: ` code `, ` message `, ` retryable `

    - ` code `: type ` string `

    - ` message `: type ` string `

    - ` retryable `: type ` boolean `

Response header ` x-request-id ` — The request ID (`req_…`). It is the `instance` of any problem and the key for `GET /v1/requests/{request_id}`.

- ` value `: type ` string `

  - pattern: ` "^req_[0-9a-hjkmnp-tv-z]{26}$" `

Response header ` Server-Timing ` — Phase durations in milliseconds (W3C Server Timing); the handler's phases break the request down. For a
response whose body size is known, `total` runs from reading the request head to writing the response head.
Streaming responses (event streams, WebSockets, chunked bodies) carry no `total` here: they report their
final phases in the terminal event (`job.succeeded`, `job.failed`, `job.canceled`) or the final job. The
time from the first request byte to the last response byte is recorded in the node's metrics and request
log (`GET /v1/requests/{request_id}`). The edge prepends `edge_auth` and `edge_upstream`.


- ` value `: type ` string `

Example:

```json
{
  "type": "https://docs.beta.b3os.org/errors#internal",
  "title": "Internal error",
  "status": 500,
  "code": "internal",
  "detail": "internal error",
  "instance": "req_01m5t4yg394wegr3j4y01qb363"
}
```

### ` 503 ` — The node or the product is not available right now (`node_unavailable`, `product_unavailable`, `capacity_unavailable`).

Content type: ` application/problem+json `

- ` value `: type ` object ` — An RFC 9457 problem. `code` is stable and listed in the errors catalog; `type` links to its entry. `detail` is human-readable and may change. Extension members appear only for the codes that document them; ignore members you do not recognize. 

  - Required fields: ` type `, ` title `, ` status `, ` code `, ` detail `

  - ` type `: type ` string `; format ` uri ` — `https://docs.beta.b3os.org/errors#<code>`.

    - example: ` "https://docs.beta.b3os.org/errors#invalid_request" `

  - ` title `: type ` string ` — Short summary of the problem type.

  - ` status `: type ` integer ` — The HTTP status code, repeated for convenience.

    - minimum: ` 400 `

    - maximum: ` 599 `

  - ` code `: type ` string ` — Stable machine-readable error code from the errors catalog.

    - pattern: ` "^[a-z][a-z0-9_]*$" `

  - ` detail `: type ` string ` — Explanation of this occurrence. Never contains secrets.

  - ` instance `: type ` string ` — The request ID (`req_…`) of the request that failed. Include it when you contact support.

    - example: ` "req_01m5t4yg394wegr3j4y01qb363" `

  - ` errors `: type ` array ` — Validation problems, one per field (`invalid_request` and the other codes that list `errors`).

    - ` array item `: type ` object ` — One validation problem.

      - Required fields: ` pointer `, ` detail `

      - ` pointer `: type ` string ` — Where the problem is: a JSON pointer into the request body (`/url`, `/steps/0/uses`), or `#query/<name>`, `#path/<name>` or `#header/<name>` for parameters. 

        - example: ` "/url" `

      - ` detail `: type ` string ` — What is wrong there.

        - example: ` "must be an absolute http or https URL" `

  - ` reason `: type ` string ` — Finer-grained cause for codes that document one (`unauthorized`, `forbidden`, `egress_denied`, `upstream_unreachable`, …).

  - ` required_scope `: type ` string ` — The scope that was missing (`forbidden` with `reason: scope`).

  - ` retry_after_s `: type ` integer ` — Same value as the `Retry-After` header, for clients that only read the body.

    - minimum: ` 0 `

  - ` limit `: type ` object ` — The limit an error refers to. IDs and current values are listed by `GET /v1/limits`.

    - Required fields: ` id `, ` limit `, ` unit `

    - ` id `: type ` string ` — Limit ID, such as `vision.scrape.rpm` or `sandboxes.concurrent`.

      - example: ` "vision.scrape.rpm" `

    - ` limit `: type ` number ` — The limit's value.

    - ` unit `: type ` string ` — What the limit counts, such as `requests`, `sandboxes`, `vcpu` or `MiB`.

    - ` window_s `: type ` integer ` — Window length in seconds for rate limits and quotas.

    - ` current `: type ` number ` — Current usage against the limit, when known.

  - ` current_status `: type ` string ` — The object's current status, for state conflicts such as `sandbox_not_running`.

  - ` upstream_status `: type ` integer ` — The HTTP status the upstream returned (`upstream_error`, `action_output_invalid`).

  - ` step `: type ` string ` — The failed step, as a step ID (routines), an index (`act`) or a path such as `beats/2/do/0` (render).

  - ` pack_error `: type ` object ` — The error a pack's error mapping chose (`upstream_error` from pack actions).

    - Required fields: ` code `, ` message `, ` retryable `

    - ` code `: type ` string `

    - ` message `: type ` string `

    - ` retryable `: type ` boolean `

Response header ` x-request-id ` — The request ID (`req_…`). It is the `instance` of any problem and the key for `GET /v1/requests/{request_id}`.

- ` value `: type ` string `

  - pattern: ` "^req_[0-9a-hjkmnp-tv-z]{26}$" `

Response header ` Server-Timing ` — Phase durations in milliseconds (W3C Server Timing); the handler's phases break the request down. For a
response whose body size is known, `total` runs from reading the request head to writing the response head.
Streaming responses (event streams, WebSockets, chunked bodies) carry no `total` here: they report their
final phases in the terminal event (`job.succeeded`, `job.failed`, `job.canceled`) or the final job. The
time from the first request byte to the last response byte is recorded in the node's metrics and request
log (`GET /v1/requests/{request_id}`). The edge prepends `edge_auth` and `edge_upstream`.


- ` value `: type ` string `

Response header ` Retry-After ` — Seconds to wait before retrying or polling again.

- ` value `: type ` integer `

  - minimum: ` 0 `

Example:

```json
{
  "type": "https://docs.beta.b3os.org/errors#node_unavailable",
  "title": "Node unavailable",
  "status": 503,
  "code": "node_unavailable",
  "detail": "Node n1 is not reachable; retry in 5 seconds",
  "instance": "req_01m5t4yg394wegr3j4y01qb363",
  "retry_after_s": 5
}
```

## Request examples

### cURL

```curl
curl -X POST 'https://beta-api.b3os.org/v1/sandboxes/sbx_01m5t68q1b590rj801nbzsqzkk/snapshot' \
  -H 'Authorization: Bearer YOUR_API_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
  "name": "deps-installed"
}'
```

### JavaScript

```javascript
const response = await fetch('https://beta-api.b3os.org/v1/sandboxes/sbx_01m5t68q1b590rj801nbzsqzkk/snapshot', {
  method: 'POST',
  headers: {
      "Authorization": "Bearer YOUR_API_TOKEN",
      "Content-Type": "application/json"
  },
  body: JSON.stringify({
    "name": "deps-installed"
  })
});

const data = await response.json();
console.log(data);
```

### Python

```python
import requests

headers = {
    'Authorization': 'Bearer YOUR_API_TOKEN'
}

response = requests.post('https://beta-api.b3os.org/v1/sandboxes/sbx_01m5t68q1b590rj801nbzsqzkk/snapshot', headers=headers, json={
  "name": "deps-installed"
})
print(response.json())
```