> ## 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.

# Replay a run

Starts a new run of a finished run's routine that reuses what the source run already did. Each top-level step that succeeded in the source run is copied: it succeeds at once with its recorded outputs, does not run its callable again (no request, no sandbox, no charge) and shows `replayed: true`. Everything else runs: `from_step` and every step downstream of it, the steps that failed, were skipped or were canceled, steps another version adds or changes (compared with the source version's step of the same id: the step as written, the pack and routine versions it pinned at publish, the steps it depends on, and the `vars` and `env` it reads), steps that read an `input` that differs from the source's (directly or through `env`), steps that wait for a signal unless the version and input are the source's, and every step downstream of one of those. `trigger` and `run` are not compared. Without `from_step`, a replay of a failed run picks up where it failed.
The new run uses the source run's version and input unless `version` or `input` is given, so a fix published as a new version can be replayed against the run that failed. Its trigger is `{type: replay, parent_run_id, from_step}`; steps that run again read what the source got from its trigger through the input. Copied steps do not count toward `routines.steps.daily`. The copied outputs and the input together are at most `routines.max_step_output_bytes` (1 MiB by default), or the replay answers 422 `replay_too_large`. Answers like `routinesCreateRun`: `?wait=`, `Accept: text/event-stream`, `webhook` and `Idempotency-Key` work the same way. 

` POST /v1/routines/runs/{run_id}/replay `

Replay a run

Starts a new run of a finished run's routine that reuses what the source run already did. Each top-level
step that succeeded in the source run is copied: it succeeds at once with its recorded outputs, does not
run its callable again (no request, no sandbox, no charge) and shows `replayed: true`. Everything else runs:
`from_step` and every step downstream of it, the steps that failed, were skipped or were canceled, steps
another version adds or changes (compared with the source version's step of the same id: the step as
written, the pack and routine versions it pinned at publish, the steps it depends on, and the `vars` and
`env` it reads), steps that read an `input` that differs from the source's (directly or through `env`),
steps that wait for a signal unless the version and input are the source's, and every step downstream of
one of those. `trigger` and `run` are not compared. Without `from_step`, a replay of a failed run picks up
where it failed.

The new run uses the source run's version and input unless `version` or `input` is given, so a fix
published as a new version can be replayed against the run that failed. Its trigger is
`{type: replay, parent_run_id, from_step}`; steps that run again read what the source got from its
trigger through the input. Copied steps do not count toward `routines.steps.daily`. The copied outputs
and the input together are at most `routines.max_step_output_bytes` (1 MiB by default), or the replay
answers 422 `replay_too_large`. Answers like `routinesCreateRun`: `?wait=`, `Accept: text/event-stream`,
`webhook` and `Idempotency-Key` work the same way.


## 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.


## Parameters

### ` run_id ` (path, required)

The run ID (`run_…`).

- ` value `: type ` string `

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

Example:

```json
"run_01m5t5fr06dx6azc42f4wbzf5s"
```

### ` wait ` (query, optional)

Seconds to wait for the job to finish before responding, from 0 to 60. If it finishes in time the response
is `200` with the finished job; otherwise `202` with the job as it is, a `Location` to poll and
`Retry-After`. `0` (the default) returns immediately.


- ` value `: type ` integer `

  - default: ` 0 `

  - minimum: ` 0 `

  - maximum: ` 60 `

### ` 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`. A retry that arrives while the first request runs gets `409
idempotency_request_in_progress` with `Retry-After`. The first request runs to completion and its response
is stored even if your client disconnects. A node keeps a bounded number of keys per organization: past
that bound a request with a new key is refused (`429 quota_exceeded`, retryable) rather than run without
its key. When a node is full, organizations holding more than their share may have their oldest stored
responses dropped; a retry with such a key gets `409 idempotency_response_evicted` and is not run again.


- ` value `: type ` string `

  - minLength: ` 1 `

  - maxLength: ` 255 `

## Request body (optional)

Content type: ` application/json `

- ` value `: type ` object `

  - ` from_step `: type ` string ` — Run this top-level step and every step downstream of it again. Absent: only the steps that did not succeed, and those downstream of them, run again.

  - ` input `: type ` object ` — The new run's input instead of the source run's; validated against the version's `inputs`. When it differs from the source's, the steps that read it (directly or through `env`) and the steps that wait for a signal run again, with every step downstream of them.

  - ` version `: type ` unknown ` — Replay with this version instead of the source run's (`ver_` ID or number). The steps it adds or changes and the steps that wait for a signal run again, with every step downstream of them.

    - ` oneOf alternative 1 `: type ` string `

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

    - ` oneOf alternative 2 `: type ` integer `

      - minimum: ` 1 `

  - ` durability `: type ` string ` — Override the version's default durability for the new run.

    - enum: ` ["ephemeral","standard","strict"] `

  - ` webhook `: type ` object ` — Where to deliver this job's events. Deliveries are `POST`s of a `WebhookEvent` signed with `B3OS-Signature: t=<unix seconds>,v1=<hex HMAC-SHA256 of "<t>.<raw body>">` using the endpoint's secret (`POST /v1/webhooks/secret`). Failed deliveries are retried with backoff for 24 hours. Delivery goes through the egress guard, so private and loopback addresses are refused. 

    - Required fields: ` url `

    - ` url `: type ` string `; format ` uri ` — An `https://` URL.

      - example: ` "https://example.com/hooks/b3os" `

      - maxLength: ` 2048 `

    - ` events `: type ` array ` — Event types to deliver. Defaults to the terminal events (`job.succeeded`, `job.failed`, `job.canceled`); `["*"]` delivers every event.

      - example: ` ["job.succeeded","job.failed"] `

      - ` array item `: type ` string `

        - maxLength: ` 64 `

  - ` 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
{
  "from_step": "summary"
}
```

## Responses

### ` 200 ` — The new run finished within `wait` seconds, or the event stream when `Accept` is `text/event-stream`.

Content type: ` application/json `

- ` value `: type ` object ` — A routine run (`run_…`); `result` is the routine's `output`.

  - Required fields: ` id `, ` object `, ` status `, ` created_at `, ` updated_at `, ` routine_id `, ` version_id `, ` version_number `, ` durability `, ` trigger `, ` input `, ` steps `

  - ` id `: type ` string `

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

  - ` object `: type ` string `

    - enum: ` ["routine_run"] `

  - ` status `: type ` string ` — `queued` → `running` → one of the terminal statuses `succeeded`, `failed` or `canceled`. A job never leaves a terminal status. 

    - enum: ` ["queued","running","succeeded","failed","canceled"] `

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

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

  - ` started_at `: type ` string `; nullable; format ` date-time `

  - ` finished_at `: type ` string `; nullable; format ` date-time `

  - ` progress `: type ` object ` — How far a job has got, in the job's own unit (pages, items, steps).

    - Required fields: ` completed `, ` unit `

    - ` completed `: type ` integer ` — Units finished, successfully or not.

      - minimum: ` 0 `

    - ` failed `: type ` integer ` — Units that failed (included in `completed`).

      - minimum: ` 0 `

    - ` total `: type ` integer `; nullable — Units expected, when known.

      - minimum: ` 0 `

    - ` unit `: type ` string ` — What is counted, such as `pages`, `items` or `steps`.

  - ` result `: type ` unknown ` — The job's output. Present once `status` is `succeeded`; the product's job type defines its shape.

  - ` error `: 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 `

  - ` 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 `

  - ` expires_at `: type ` string `; nullable; format ` date-time ` — When the job's results are deleted (retention); `null` while the job is not terminal.

  - ` 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"} `

  - ` webhook `: type ` object ` — Where to deliver this job's events. Deliveries are `POST`s of a `WebhookEvent` signed with `B3OS-Signature: t=<unix seconds>,v1=<hex HMAC-SHA256 of "<t>.<raw body>">` using the endpoint's secret (`POST /v1/webhooks/secret`). Failed deliveries are retried with backoff for 24 hours. Delivery goes through the egress guard, so private and loopback addresses are refused. 

    - Required fields: ` url `

    - ` url `: type ` string `; format ` uri ` — An `https://` URL.

      - example: ` "https://example.com/hooks/b3os" `

      - maxLength: ` 2048 `

    - ` events `: type ` array ` — Event types to deliver. Defaults to the terminal events (`job.succeeded`, `job.failed`, `job.canceled`); `["*"]` delivers every event.

      - example: ` ["job.succeeded","job.failed"] `

      - ` array item `: type ` string `

        - maxLength: ` 64 `

  - ` routine_id `: type ` string `

  - ` version_id `: type ` string `

  - ` version_number `: type ` integer `

  - ` durability `: type ` string `

    - enum: ` ["ephemeral","standard","strict"] `

  - ` trigger `: type ` object ` — How the run started (the `trigger` context of its expressions).

    - Required fields: ` type `

    - ` type `: type ` string `

      - enum: ` ["api","cron","interval","webhook","action","routine","replay"] `

    - ` id `: type ` string ` — The trigger ID (cron, interval, webhook, action).

    - ` occurrence_id `: type ` string ` — Cron and interval occurrence, used to deduplicate fires.

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

    - ` hook_id `: type ` string `

    - ` delivery_id `: type ` string `

    - ` subscription_id `: type ` string ` — The trigger subscription that delivered the event (action triggers).

    - ` event_id `: type ` string ` — The pack trigger event's ID (action triggers).

    - ` parent_run_id `: type ` string ` — For sub-routine runs, the calling run; for replays, the source run.

    - ` parent_step_id `: type ` string `

    - ` from_step `: type ` string ` — For replays started with `from_step`, that step.

  - ` input `: type ` object `

  - ` summary `: type ` string ` — The run's outcome line: when the routine's `output` is an object with a non-empty `summary` string, that string on one line, cut to 140 characters (an ellipsis marks the cut). Absent otherwise. Run lists, the run's terminal event and its webhook carry it, so a list of runs says what each one did. 

    - maxLength: ` 140 `

  - ` steps `: type ` array ` — Top-level steps in definition order.

    - ` array item `: type ` object `

      - Required fields: ` id `, ` status `, ` attempt `

      - ` id `: type ` string ` — The step ID from the definition.

      - ` uses `: type ` string `

      - ` item_index `: type ` integer ` — Position in the map's list, for steps inside a map body.

      - ` status `: type ` string `

        - enum: ` ["pending","running","waiting","retrying","succeeded","failed","skipped","canceled"] `

      - ` attempt `: type ` integer ` — The attempt this execution is. Retries add one; so does a node restart while the step ran (the earlier attempt's result, should it arrive, is discarded).

        - minimum: ` 1 `

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

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

      - ` duration_ms `: type ` number `

      - ` outputs `: type ` unknown ` — The step's outputs, once it succeeded.

      - ` error `: 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 `

      - ` map `: type ` object ` — Item counts for a map step.

        - ` total `: type ` integer `

        - ` succeeded `: type ` integer `

        - ` failed `: type ` integer `

        - ` running `: type ` integer `

      - ` waiting_for `: type ` object ` — What a waiting step waits for.

        - ` signal `: type ` string `

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

      - ` replayed `: type ` boolean ` — A replay copied this step's outputs from its source run; the step did not run. Absent otherwise.

        - enum: ` [true] `

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": "run_01m5t7a3k2xq9zb4c8d6e0f1g2",
  "object": "routine_run",
  "status": "succeeded",
  "routine_id": "rtn_01m5t6vhkw4a8fa4tb5w4ffz37",
  "version_id": "ver_01m5t6ncrsssrysy1p2fbn2pgf",
  "version_number": 2,
  "durability": "standard",
  "trigger": {
    "type": "replay",
    "parent_run_id": "run_01m5t5fr06dx6azc42f4wbzf5s",
    "from_step": "summary"
  },
  "input": {
    "topic": "pricing"
  },
  "result": {
    "summary": "Prices did not change today."
  },
  "summary": "Prices did not change today.",
  "steps": [
    {
      "id": "page",
      "uses": "vision/scrape@1",
      "status": "succeeded",
      "attempt": 1,
      "started_at": "2026-10-25T20:10:00.001Z",
      "finished_at": "2026-10-25T20:10:00.001Z",
      "duration_ms": 0.004,
      "replayed": true
    },
    {
      "id": "summary",
      "uses": "infer/chat@1",
      "status": "succeeded",
      "attempt": 1,
      "started_at": "2026-10-25T20:10:00.001Z",
      "finished_at": "2026-10-25T20:10:01.180Z",
      "duration_ms": 1179.2
    }
  ],
  "progress": {
    "completed": 2,
    "total": 2,
    "unit": "steps"
  },
  "created_at": "2026-10-25T20:10:00.000Z",
  "updated_at": "2026-10-25T20:10:01.180Z",
  "started_at": "2026-10-25T20:10:00.000Z",
  "finished_at": "2026-10-25T20:10:01.180Z",
  "timing": {
    "dispatch_ms": 0.02,
    "steps_ms": 1179.3,
    "total_ms": 1180.1
  },
  "expires_at": "2026-11-24T20:10:01.180Z",
  "metadata": {}
}
```

### ` 202 ` — The new run was accepted and is still running.

Content type: ` application/json `

- ` value `: type ` object ` — A routine run (`run_…`); `result` is the routine's `output`.

  - Required fields: ` id `, ` object `, ` status `, ` created_at `, ` updated_at `, ` routine_id `, ` version_id `, ` version_number `, ` durability `, ` trigger `, ` input `, ` steps `

  - ` id `: type ` string `

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

  - ` object `: type ` string `

    - enum: ` ["routine_run"] `

  - ` status `: type ` string ` — `queued` → `running` → one of the terminal statuses `succeeded`, `failed` or `canceled`. A job never leaves a terminal status. 

    - enum: ` ["queued","running","succeeded","failed","canceled"] `

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

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

  - ` started_at `: type ` string `; nullable; format ` date-time `

  - ` finished_at `: type ` string `; nullable; format ` date-time `

  - ` progress `: type ` object ` — How far a job has got, in the job's own unit (pages, items, steps).

    - Required fields: ` completed `, ` unit `

    - ` completed `: type ` integer ` — Units finished, successfully or not.

      - minimum: ` 0 `

    - ` failed `: type ` integer ` — Units that failed (included in `completed`).

      - minimum: ` 0 `

    - ` total `: type ` integer `; nullable — Units expected, when known.

      - minimum: ` 0 `

    - ` unit `: type ` string ` — What is counted, such as `pages`, `items` or `steps`.

  - ` result `: type ` unknown ` — The job's output. Present once `status` is `succeeded`; the product's job type defines its shape.

  - ` error `: 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 `

  - ` 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 `

  - ` expires_at `: type ` string `; nullable; format ` date-time ` — When the job's results are deleted (retention); `null` while the job is not terminal.

  - ` 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"} `

  - ` webhook `: type ` object ` — Where to deliver this job's events. Deliveries are `POST`s of a `WebhookEvent` signed with `B3OS-Signature: t=<unix seconds>,v1=<hex HMAC-SHA256 of "<t>.<raw body>">` using the endpoint's secret (`POST /v1/webhooks/secret`). Failed deliveries are retried with backoff for 24 hours. Delivery goes through the egress guard, so private and loopback addresses are refused. 

    - Required fields: ` url `

    - ` url `: type ` string `; format ` uri ` — An `https://` URL.

      - example: ` "https://example.com/hooks/b3os" `

      - maxLength: ` 2048 `

    - ` events `: type ` array ` — Event types to deliver. Defaults to the terminal events (`job.succeeded`, `job.failed`, `job.canceled`); `["*"]` delivers every event.

      - example: ` ["job.succeeded","job.failed"] `

      - ` array item `: type ` string `

        - maxLength: ` 64 `

  - ` routine_id `: type ` string `

  - ` version_id `: type ` string `

  - ` version_number `: type ` integer `

  - ` durability `: type ` string `

    - enum: ` ["ephemeral","standard","strict"] `

  - ` trigger `: type ` object ` — How the run started (the `trigger` context of its expressions).

    - Required fields: ` type `

    - ` type `: type ` string `

      - enum: ` ["api","cron","interval","webhook","action","routine","replay"] `

    - ` id `: type ` string ` — The trigger ID (cron, interval, webhook, action).

    - ` occurrence_id `: type ` string ` — Cron and interval occurrence, used to deduplicate fires.

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

    - ` hook_id `: type ` string `

    - ` delivery_id `: type ` string `

    - ` subscription_id `: type ` string ` — The trigger subscription that delivered the event (action triggers).

    - ` event_id `: type ` string ` — The pack trigger event's ID (action triggers).

    - ` parent_run_id `: type ` string ` — For sub-routine runs, the calling run; for replays, the source run.

    - ` parent_step_id `: type ` string `

    - ` from_step `: type ` string ` — For replays started with `from_step`, that step.

  - ` input `: type ` object `

  - ` summary `: type ` string ` — The run's outcome line: when the routine's `output` is an object with a non-empty `summary` string, that string on one line, cut to 140 characters (an ellipsis marks the cut). Absent otherwise. Run lists, the run's terminal event and its webhook carry it, so a list of runs says what each one did. 

    - maxLength: ` 140 `

  - ` steps `: type ` array ` — Top-level steps in definition order.

    - ` array item `: type ` object `

      - Required fields: ` id `, ` status `, ` attempt `

      - ` id `: type ` string ` — The step ID from the definition.

      - ` uses `: type ` string `

      - ` item_index `: type ` integer ` — Position in the map's list, for steps inside a map body.

      - ` status `: type ` string `

        - enum: ` ["pending","running","waiting","retrying","succeeded","failed","skipped","canceled"] `

      - ` attempt `: type ` integer ` — The attempt this execution is. Retries add one; so does a node restart while the step ran (the earlier attempt's result, should it arrive, is discarded).

        - minimum: ` 1 `

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

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

      - ` duration_ms `: type ` number `

      - ` outputs `: type ` unknown ` — The step's outputs, once it succeeded.

      - ` error `: 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 `

      - ` map `: type ` object ` — Item counts for a map step.

        - ` total `: type ` integer `

        - ` succeeded `: type ` integer `

        - ` failed `: type ` integer `

        - ` running `: type ` integer `

      - ` waiting_for `: type ` object ` — What a waiting step waits for.

        - ` signal `: type ` string `

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

      - ` replayed `: type ` boolean ` — A replay copied this step's outputs from its source run; the step did not run. Absent otherwise.

        - enum: ` [true] `

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 ` Location ` — URL of the created job or object; poll it with `GET`.

- ` value `: type ` string `; format ` uri-reference `

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

- ` value `: type ` integer `

  - minimum: ` 0 `

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": "run_01m5t7a3k2xq9zb4c8d6e0f1g2",
  "object": "routine_run",
  "status": "queued",
  "routine_id": "rtn_01m5t6vhkw4a8fa4tb5w4ffz37",
  "version_id": "ver_01m5t6ncrsssrysy1p2fbn2pgf",
  "version_number": 2,
  "durability": "standard",
  "trigger": {
    "type": "replay",
    "parent_run_id": "run_01m5t5fr06dx6azc42f4wbzf5s"
  },
  "input": {
    "topic": "pricing"
  },
  "steps": [],
  "created_at": "2026-10-25T20:10:00.000Z",
  "updated_at": "2026-10-25T20:10:00.000Z",
  "started_at": null,
  "finished_at": null,
  "expires_at": null,
  "metadata": {}
}
```

### ` 400 ` — `from_step` names no top-level step of the version (`invalid_request`, with `errors`).

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": "from_step: version 2 has no top-level step sumary",
  "instance": "req_01m5t4yg394wegr3j4y01qb363",
  "errors": [
    {
      "pointer": "/from_step",
      "detail": "must name a top-level step of the version"
    }
  ]
}
```

### ` 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"
}
```

### ` 402 ` — The organization has no credits left, or the key reached its spend cap.

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#credits_exhausted",
  "title": "Credits exhausted",
  "status": 402,
  "code": "credits_exhausted",
  "detail": "Organization org_01m5t5hthd29mm5wpza5ndd6mm has no credits left",
  "instance": "req_01m5t4yg394wegr3j4y01qb363"
}
```

### ` 403 ` — The key that published the active version is revoked (`run_as_revoked`).

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#run_as_revoked",
  "title": "Publishing key revoked",
  "status": 403,
  "code": "run_as_revoked",
  "detail": "key_01m5t5gb92a5zncjx654gevx4p was revoked; publish a new version to resume",
  "instance": "req_01m5t4yg394wegr3j4y01qb363"
}
```

### ` 404 ` — No such run in this project (`run_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#run_not_found",
  "title": "Run not found",
  "status": 404,
  "code": "run_not_found",
  "detail": "No run run_01m5t5fr06dx6azc42f4wbzf5s in this project",
  "instance": "req_01m5t4yg394wegr3j4y01qb363"
}
```

### ` 409 ` — The source run is still `queued` or `running` (`run_not_finished`), or the `Idempotency-Key` was used for a different request (`idempotency_key_conflict`).

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#run_not_finished",
  "title": "Run not finished",
  "status": 409,
  "code": "run_not_finished",
  "detail": "run_01m5t5fr06dx6azc42f4wbzf5s is running; replay it once it finished, or cancel it first",
  "instance": "req_01m5t4yg394wegr3j4y01qb363",
  "current_status": "running"
}
```

### ` 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 input does not match the version's `inputs` schema (`run_input_invalid`), `webhook.url` is not an absolute `https://` URL (`invalid_webhook_url`), or the copied outputs with the input are over `routines.max_step_output_bytes` (`replay_too_large`).

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#replay_too_large",
  "title": "Replay too large",
  "status": 422,
  "code": "replay_too_large",
  "detail": "the 3 copied steps' outputs and the input are 1210388 bytes; a replay copies at most 1048576 (routines.max_step_output_bytes): replay from an earlier step",
  "instance": "req_01m5t4yg394wegr3j4y01qb363"
}
```

### ` 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/routines/runs/run_01m5t5fr06dx6azc42f4wbzf5s/replay' \
  -H 'Authorization: Bearer YOUR_API_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
  "from_step": "summary"
}'
```

### JavaScript

```javascript
const response = await fetch('https://beta-api.b3os.org/v1/routines/runs/run_01m5t5fr06dx6azc42f4wbzf5s/replay', {
  method: 'POST',
  headers: {
      "Authorization": "Bearer YOUR_API_TOKEN",
      "Content-Type": "application/json"
  },
  body: JSON.stringify({
    "from_step": "summary"
  })
});

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/routines/runs/run_01m5t5fr06dx6azc42f4wbzf5s/replay', headers=headers, json={
  "from_step": "summary"
})
print(response.json())
```