{
  "openapi": "3.1.1",
  "info": {
    "title": "BoxRouter API",
    "version": "0.10.281",
    "description": "Hosted sandbox control using a BoxRouter API key. Provider credentials are\nconfigured separately and never included in workload requests. Same-origin browser\nsessions are also accepted. Browser mutations require the configured Origin and\nthe session-bound X-CSRF-Token; after an organization switch, every cookie-authenticated\nmutation must also send X-BoxRouter-Selection-Version with the version read from /auth/me.\nA stale version returns 409 organization_changed before side effects; its details contain\nthe current selection_version. Bearer keys do not require browser CSRF or selection headers. Core adapters\nexecute on BoxRouter servers.\nSandbox IDs are BoxRouter resource IDs; every access is scoped to the caller's\nworkspace. Routing occurs only at creation. Subsequent operations retain the\noriginal provider, upstream account and billing mode.\nMutation endpoints accept an Idempotency-Key. Clients should generate one per\nlogical mutation and retain it for reconciliation. The server records workspace,\nmethod, path and request identity before dispatch. Buffered requests include the full\nbody hash. Streaming uploads reserve the key first, lock concurrent dispatch, and\nfinalize the body hash as bytes arrive; interrupted uploads remain unresolved and\nmust not be redispatched. A replay must validate the complete body before returning\na recorded success. Reusing a key with different input\nreturns 409; identical input returns the recorded result or an unresolved-operation\nerror without dispatching again. Records with unknown outcomes are retained until\nresolved; completed records remain available for at least 24 hours. This does not\npromise exactly-once upstream execution or authorize automatic mutation retries.\n\n## Guarantees\n\nEach operation's description states what you can rely on, what you can set and what is not promised. These rules apply to all operations:\n\n- File operations may act with more authority than the command user: do not rely on file permissions to keep the file API out. Commands run as the command user.\n- Some features need capabilities. A request that names them runs only on infrastructure that supports them, and an operation the sandbox was not created for returns a clear error; behaviour never changes silently.\n"
  },
  "servers": [
    {
      "url": "https://api.boxrouter.ai/api/v1"
    }
  ],
  "security": [
    {
      "BoxRouterKey": []
    },
    {
      "BrowserSession": []
    }
  ],
  "tags": [
    {
      "name": "agents",
      "description": "Discover launch manifests available to this workspace."
    },
    {
      "name": "identity",
      "description": "Browser sign-in and self-service API-key administration."
    },
    {
      "name": "organizations",
      "description": "Browser-only team organizations, invitations and membership administration."
    },
    {
      "name": "launches",
      "description": "Create an interactive sandbox from an agent manifest."
    },
    {
      "name": "launch-runs",
      "description": "Reserve, list, observe, and stop unattended multi-copy launch runs and their copies."
    },
    {
      "name": "sandboxes",
      "description": "Create and manage owned sandbox resources."
    },
    {
      "name": "commands",
      "description": "Execute Bash commands in an existing sandbox."
    },
    {
      "name": "files",
      "description": "Transfer exact file bytes within an existing sandbox."
    },
    {
      "name": "providers",
      "description": "Discover the caller's eligible supply and capabilities."
    },
    {
      "name": "operations",
      "description": "Reconcile uncertain mutations without replaying them."
    },
    {
      "name": "provider-accounts",
      "description": "Manage encrypted hosted BYOK connections separately from workload requests."
    },
    {
      "name": "credits",
      "description": "Prepaid credit balance, purchases and saved payment methods; never required for BYOK work."
    },
    {
      "name": "spend-limits",
      "description": "The cap on the managed compute a workspace can spend; BYOK work never counts."
    },
    {
      "name": "processes",
      "description": "Background commands with streamed output and completion on every provider; stdin where supported."
    },
    {
      "name": "previews",
      "description": "URLs and enforced credentials for sandbox ports on every provider."
    },
    {
      "name": "volumes",
      "description": "BoxRouter Volumes: one folder with checkpoints, restorable on any provider"
    },
    {
      "name": "terminals",
      "description": "Real PTY sessions on every provider through a guest helper."
    },
    {
      "name": "secrets",
      "description": "Manage workspace-scoped secret values without returning them."
    },
    {
      "name": "artifacts",
      "description": "Temporary workspace-owned inputs for provider builds and file transfers."
    },
    {
      "name": "pricing",
      "description": "The providers' published prices, as dated versions anyone can read without a key."
    },
    {
      "name": "github",
      "description": "The shared GitHub App connection used by Deployments and Actions; installations remain workspace-scoped."
    },
    {
      "name": "actions",
      "description": "GitHub Actions settings, policy previews and workspace-owned run, job and placement projections."
    },
    {
      "name": "routing",
      "description": "Workspace-wide routing authority, per-provider funding order and availability preview."
    },
    {
      "name": "images",
      "description": "Prepare and remove workspace-scoped provider copies of images."
    }
  ],
  "paths": {
    "/agents": {
      "get": {
        "tags": [
          "agents"
        ],
        "operationId": "listAgents",
        "x-speakeasy-group": "agents",
        "x-speakeasy-name-override": "list",
        "summary": "List launch agents",
        "description": "List the launch manifests available to this workspace. The response includes\nnames, display names, descriptions, declared secret names and preview ports.\nIt never includes commands, file contents or secret values.\n",
        "responses": {
          "200": {
            "description": "Available launch agents.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AgentPage"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/agents/{name}": {
      "parameters": [
        {
          "name": "name",
          "in": "path",
          "required": true,
          "description": "Launch agent name.",
          "schema": {
            "type": "string",
            "minLength": 1,
            "maxLength": 63,
            "pattern": "^[a-z][a-z0-9-]{0,62}$"
          }
        }
      ],
      "get": {
        "tags": [
          "agents"
        ],
        "operationId": "getAgent",
        "x-speakeasy-group": "agents",
        "x-speakeasy-name-override": "get",
        "summary": "Get a launch agent manifest",
        "description": "Returns a workspace-available manifest. Unknown names return agent_not_found.",
        "responses": {
          "200": {
            "description": "Agent metadata and its launch manifest.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AgentDetails"
                }
              }
            }
          },
          "404": {
            "description": "No available agent has this name.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AgentNotFoundErrorResponse"
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/launches": {
      "post": {
        "tags": [
          "launches"
        ],
        "operationId": "createLaunch",
        "x-speakeasy-group": "launches",
        "x-speakeasy-name-override": "create",
        "summary": "Create an agent launch",
        "description": "Create one workspace-owned sandbox and prepare it from a catalog agent or inline\nmanifest. `overrides.lifetime_seconds` requests a lifetime in seconds in place of\nthe manifest value; null there or in the manifest asks for a sandbox with no lifetime.\nThe required Idempotency-Key identifies one logical launch; retry an\nuncertain request with the same key and body. BoxRouter validates the manifest,\nthe secrets, the routes and the funding first and answers 400, 402 or 409 with outcome\n`not_started` for a launch it cannot start; it returns 202 only after the launch\noperation is durably accepted. Poll the operation URL from Location for\nqueued/running status and phase progress. A matching key returns the same operation,\nincluding the original result. New requests and matching retries both return HTTP 202.\nA key used with different input returns 409 and does not start another launch.\nSetup, file, background and preview preparation failures destroy the newly created\nsandbox before the operation becomes failed.\n\nSecret values supplied in secret_values are used only for this request and are\nnever stored or returned. Names declared by the manifest can instead resolve from\nthe workspace secret store. The successful operation contains the sandbox ID,\nphase results, preview URLs and enforced expiry in result.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/LaunchIdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LaunchRequest"
              },
              "example": {
                "manifest": {
                  "name": "hello-agent",
                  "command": "bash",
                  "setup": [
                    "echo ready > /tmp/ready.txt"
                  ]
                }
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Launch operation accepted, or recovered for this idempotency key.",
            "headers": {
              "Location": {
                "required": true,
                "description": "URL to poll for launch status and preparation phase progress.",
                "schema": {
                  "type": "string",
                  "format": "uri-reference"
                }
              },
              "Retry-After": {
                "description": "Minimum delay in seconds before polling the operation URL.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              },
              "X-Request-ID": {
                "$ref": "#/components/headers/RequestId"
              },
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LaunchOperation"
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed or one or more named secrets are missing.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LaunchInputErrorResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "description": "Credit is insufficient or a configured managed spend limit would be exceeded. No provider create or hold is committed.",
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/RequestId"
              },
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "description": "The requested catalog agent does not exist.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AgentNotFoundErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "The idempotency key conflicts or no route can satisfy the launch before the operation is accepted. Preparation phase failures are returned on the accepted operation when polled.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LaunchConflictErrorResponse"
                }
              }
            }
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/launches/{operation_id}": {
      "parameters": [
        {
          "name": "operation_id",
          "in": "path",
          "required": true,
          "description": "Workspace-owned launch operation returned by create.",
          "schema": {
            "type": "string",
            "minLength": 1
          }
        }
      ],
      "get": {
        "tags": [
          "launches"
        ],
        "operationId": "getLaunchOperation",
        "x-speakeasy-group": "launches",
        "x-speakeasy-name-override": "get_operation",
        "summary": "Get launch status and phase progress",
        "description": "Returns the durable status of one launch operation owned by the caller's workspace.\nPoll while status is queued or running, respecting Retry-After when present. A\nsucceeded operation includes result; a failed operation includes the original\nstructured API error and its HTTP status. Secret values are never included.\n",
        "responses": {
          "200": {
            "description": "Current launch operation status.",
            "headers": {
              "Retry-After": {
                "description": "Minimum delay in seconds before polling again while non-terminal.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              },
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LaunchOperation"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/launches/{operation_id}/settings": {
      "parameters": [
        {
          "name": "operation_id",
          "in": "path",
          "required": true,
          "description": "Workspace-owned launch operation returned by create.",
          "schema": {
            "type": "string",
            "minLength": 1
          }
        }
      ],
      "get": {
        "tags": [
          "launches"
        ],
        "operationId": "getLaunchSettings",
        "x-speakeasy-group": "launches",
        "x-speakeasy-name-override": "get_settings",
        "summary": "Get what a launch asked for",
        "description": "Returns the choices one launch was created with: the catalog agent or the caller's own\nsource, whether BoxRouter picked the provider or the caller chose one, and the names of\nthe secrets it used. Every client that creates a launch (the dashboard, the CLI, the\nSDKs) is recorded the same way, so any of them can show or repeat it. Secret values are\nnever recorded or returned. A launch created before settings were recorded is 404.\n",
        "responses": {
          "200": {
            "description": "The launch's recorded settings.",
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LaunchSettings"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/launches/{operation_id}/command": {
      "parameters": [
        {
          "name": "operation_id",
          "in": "path",
          "required": true,
          "description": "Workspace-owned launch operation returned by create.",
          "schema": {
            "type": "string",
            "minLength": 1
          }
        }
      ],
      "get": {
        "tags": [
          "launches"
        ],
        "operationId": "getLaunchCommand",
        "x-speakeasy-group": "launches",
        "x-speakeasy-name-override": "get_command",
        "summary": "Get unattended command state",
        "description": "Returns the observed state of the unattended command attached to a launch owned by the\ncaller's workspace. Observation waits up to five seconds. While the command is running,\ncall this endpoint again to observe its state. `unknown` means the outcome could not be\nconfirmed; it is never inferred from a missing sandbox or an observation failure.\nA launch with no recorded unattended command returns 404. This response never contains\ncommand text, environment variables, process identity, stdout, stderr or other output.\n`timed_out` with exit code 124 means the armed command timer was observed to expire; an\nordinary command exit with code 124 remains `exited`.\n",
        "responses": {
          "200": {
            "description": "Current bounded observation of the unattended command.",
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LaunchCommand"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/launch-runs": {
      "get": {
        "tags": [
          "launch-runs"
        ],
        "operationId": "listLaunchRuns",
        "x-speakeasy-group": "launchRuns",
        "x-speakeasy-name-override": "list",
        "summary": "List launch runs",
        "description": "List the authenticated workspace's launch runs, newest first, as lightweight summaries.\nRows contain no copy items, specs, command data or outputs; read getLaunchRun for one\nrun's copies. `total_copies` and `live_copies` cover every run in the workspace, not\nonly the returned page. A live copy is one whose sandbox has not been confirmed absent,\nincluding copies that are stopping. The read uses stored metadata only and makes no\nprovider calls. Responses are private to the workspace and must not be cached.\n\nIf launch-run copies are not available to you, the read still answers 200, with `available`\nfalse, no runs and zero totals.\n\n`next_cursor` is an opaque, workspace-scoped value for the next page and is null on the\nlast page. A cursor from another workspace or a malformed cursor is invalid_request.\n",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum number of runs in this page.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 50,
              "default": 20
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "Opaque next_cursor from the previous page of this workspace's list.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 1024
            }
          }
        ],
        "responses": {
          "200": {
            "description": "One page of run summaries with workspace-wide copy totals.",
            "headers": {
              "Cache-Control": {
                "description": "The response is private and must not be cached.",
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              },
              "X-Request-ID": {
                "$ref": "#/components/headers/RequestId"
              },
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LaunchRunList"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "description": "The limit or cursor is invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvalidRequestErrorResponse"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "post": {
        "tags": [
          "launch-runs"
        ],
        "operationId": "createLaunchRun",
        "x-speakeasy-group": "launchRuns",
        "x-speakeasy-name-override": "create",
        "summary": "Start an unattended launch run",
        "description": "Reserve one workspace-owned run and all requested copies atomically. The existing\nlaunch request fields select exactly one catalog agent or inline manifest; `copies`\nis required. Acceptance returns 202 with a Location for metadata polling and makes\nno provider create before the executor claims each copy. Reuse the same\nIdempotency-Key and identical body to recover an uncertain acceptance; a changed\nbody conflicts and never creates another run.\n\nCredential selectors are resolved at each copy claim. Secret values and provider\ntokens are never stored. Saved secrets are re-read by name, so rotation can affect\nlater copies. Inline secret_values, interactive launches, and unsupported manifest\nfeatures are refused before reservation. The feature remains opt-in until compatible\nclients are released.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/LaunchIdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LaunchRunRequest"
              },
              "example": {
                "manifest": {
                  "name": "nightly-check",
                  "command": "python3 check.py",
                  "interactive": false
                },
                "copies": 3
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Run and all copy rows were durably accepted, or recovered by idempotency key.",
            "headers": {
              "Location": {
                "required": true,
                "description": "URL for provider-free metadata polling of this run.",
                "schema": {
                  "type": "string",
                  "format": "uri-reference"
                }
              },
              "X-Request-ID": {
                "$ref": "#/components/headers/RequestId"
              },
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LaunchRunDocument"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "description": "The selected agent or credential reference is not visible to this workspace.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "The key conflicts with a previous request, no eligible route can satisfy the run, or launch-run copies are not available to you (`capability_unavailable`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LaunchConflictErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "The request is invalid or asks for an unsupported unattended-run feature.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LaunchRunRequestErrorResponse"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/launch-runs/{run_id}": {
      "get": {
        "tags": [
          "launch-runs"
        ],
        "operationId": "getLaunchRun",
        "x-speakeasy-group": "launchRuns",
        "x-speakeasy-name-override": "get",
        "summary": "Read launch run metadata",
        "description": "Read the stored run row and copy rows only. This response excludes command data and\noutput fields and makes no provider calls. `include=command` opts into bounded state\nand exit-code observations for active copies; the server uses at most eight\nobservations at once and one five-second response deadline. Unknown, hung, saturated,\nor failed observations return `unknown`. Neither variant exposes command text,\noutputs, process handles, or credentials. Foreign and missing IDs have the same 404\nresponse.\n",
        "parameters": [
          {
            "name": "run_id",
            "in": "path",
            "required": true,
            "description": "Workspace-owned launch run ID returned by createLaunchRun.",
            "schema": {
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "include",
            "in": "query",
            "required": false,
            "description": "Omit for provider-free metadata; use command for bounded command observations.",
            "schema": {
              "type": "string",
              "enum": [
                "command"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Stored metadata, with bounded command observations only when requested.",
            "headers": {
              "Cache-Control": {
                "description": "The response is private and must not be cached.",
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              },
              "X-Request-ID": {
                "$ref": "#/components/headers/RequestId"
              },
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "anyOf": [
                    {
                      "$ref": "#/components/schemas/LaunchRunDocument"
                    },
                    {
                      "$ref": "#/components/schemas/LaunchRunWithCommand"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The include value is unsupported.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvalidRequestErrorResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "description": "Launch-run copies are not available to you (`capability_unavailable`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CopiesUnavailableErrorResponse"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/launch-runs/{run_id}/stop": {
      "post": {
        "tags": [
          "launch-runs"
        ],
        "operationId": "stopLaunchRun",
        "x-speakeasy-group": "launchRuns",
        "x-speakeasy-name-override": "stop",
        "summary": "Stop a launch run",
        "description": "Set the workspace-owned run's desired state to stopped and request copy cancellation. The request is idempotent; repeating stop returns the original stop timestamp. This does not imply that the provider sandbox was destroyed. Foreign and missing IDs have the same 404 response.",
        "parameters": [
          {
            "name": "run_id",
            "in": "path",
            "required": true,
            "description": "Workspace-owned launch run ID returned by createLaunchRun.",
            "schema": {
              "type": "string",
              "minLength": 1
            }
          }
        ],
        "responses": {
          "202": {
            "description": "Stop was accepted or had already been accepted.",
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/RequestId"
              },
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LaunchRunStopAccepted"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "description": "Launch-run copies are not available to you (`capability_unavailable`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CopiesUnavailableErrorResponse"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/launch-runs/{run_id}/copies/{copy_index}/destroy": {
      "post": {
        "tags": [
          "launch-runs"
        ],
        "operationId": "destroyLaunchRunCopy",
        "x-speakeasy-group": "launchRuns",
        "x-speakeasy-name-override": "destroy_copy",
        "summary": "Destroy one launch-run copy",
        "description": "Durably request cleanup of one copy of a workspace-owned run; the run and its other\ncopies keep running. Acceptance records the request only: no provider call is made\nduring the request, and `stopping` does not mean the sandbox is gone. The copy's\nstatus in getLaunchRun becomes `stopped` only after its absence is confirmed; a queued\ncopy that was never dispatched has no sandbox and stops at once.\n\nThe request is idempotent. Retrying it, or destroying a copy that is already stopping\nor stopped, returns the same 202 and leaves the copy's state and timestamps unchanged.\nForeign and missing run IDs and copy indexes have the same 404 response. Responses are\nprivate and must not be cached.\n",
        "parameters": [
          {
            "name": "run_id",
            "in": "path",
            "required": true,
            "description": "Workspace-owned launch run ID returned by createLaunchRun.",
            "schema": {
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "copy_index",
            "in": "path",
            "required": true,
            "description": "Zero-based copy index from the run's items.",
            "schema": {
              "type": "integer",
              "minimum": 0
            }
          }
        ],
        "responses": {
          "202": {
            "description": "The cleanup request was recorded or had already been recorded.",
            "headers": {
              "Cache-Control": {
                "description": "The response is private and must not be cached.",
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              },
              "X-Request-ID": {
                "$ref": "#/components/headers/RequestId"
              },
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LaunchRunCopyDestroyAccepted"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "description": "Launch-run copies are not available to you (`capability_unavailable`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CopiesUnavailableErrorResponse"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/repositories/{owner}/{repo}/access": {
      "parameters": [
        {
          "name": "owner",
          "in": "path",
          "required": true,
          "description": "GitHub owner of the repository.",
          "schema": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          }
        },
        {
          "name": "repo",
          "in": "path",
          "required": true,
          "description": "GitHub repository name.",
          "schema": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          }
        }
      ],
      "get": {
        "tags": [
          "launches"
        ],
        "operationId": "checkRepositoryAccess",
        "x-speakeasy-group": "launches",
        "x-speakeasy-name-override": "check_repository_access",
        "summary": "Check whether this workspace can read a repository",
        "description": "Answers, without launching anything, whether the caller's workspace can read the\nrepository: public repositories directly, private ones through the workspace's linked\nGitHub App installation. A repository that cannot be read is a 200 with readable false\nand the refusal's code, message and fix. When readable, the answer also names the commit\nthe default branch (or the requested ref) points at, the repository's top-level entries\n(directories end in a slash) and the recipe a launch would use. Results are cached per\ncommit and never stored in a response cache.\n",
        "parameters": [
          {
            "name": "ref",
            "in": "query",
            "required": false,
            "description": "Branch, tag or commit to check instead of the default branch.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 256
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Whether the repository is readable, with the detected recipe when it is.",
            "headers": {
              "Cache-Control": {
                "description": "Always no-store.",
                "schema": {
                  "type": "string"
                }
              },
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RepositoryAccess"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/github/installations": {
      "get": {
        "tags": [
          "github"
        ],
        "operationId": "listGithubInstallations",
        "x-boxrouter-authority": "read",
        "x-speakeasy-group": "github",
        "x-speakeasy-name-override": "list_installations",
        "summary": "List GitHub App installations linked to this workspace",
        "description": "Requires read authority in the authenticated workspace. Results include only\ninstallations linked to that workspace; an installation ID supplied by a caller\nis not authority. Empty workspaces return an empty page. This is a read and never\ninstalls, uninstalls or relinks the App.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/Cursor"
          },
          {
            "$ref": "#/components/parameters/Limit"
          }
        ],
        "responses": {
          "200": {
            "description": "Workspace-owned linked installations in stable ID order.",
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GitHubInstallationPage"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/github/installations/{installation_id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/InstallationId"
        }
      ],
      "delete": {
        "tags": [
          "github"
        ],
        "operationId": "unlinkGithubInstallation",
        "x-boxrouter-authority": "admin",
        "x-speakeasy-group": "github",
        "x-speakeasy-name-override": "unlink_installation",
        "summary": "Unlink a GitHub App installation from this workspace",
        "description": "Requires workspace administrator authority. Browser-session calls require the CSRF\ntoken and configured Origin. An Idempotency-Key identifies this one unlink request;\nan identical replay returns its recorded result, a changed request under that key\nconflicts, and an unknown GitHub or storage outcome is reconciled without replay.\nUnlinking prevents new Actions work and does not uninstall the shared App from\nGitHub or cancel already accepted workflow runs.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/Csrf"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "204": {
            "description": "Installation link removed from this workspace; the GitHub App remains installed.",
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/github/repositories": {
      "get": {
        "tags": [
          "github"
        ],
        "operationId": "listGithubRepositories",
        "x-boxrouter-authority": "read",
        "x-speakeasy-group": "github",
        "x-speakeasy-name-override": "list_repositories",
        "summary": "List repositories visible through a linked installation",
        "description": "Requires read authority in the authenticated workspace. The installation must be\nlinked to that workspace and its current GitHub permissions are revalidated; names\nare descriptive while stable repository IDs bind settings and work. Results contain\nno installation access credentials. Empty installations return an empty page.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/InstallationQuery"
          },
          {
            "$ref": "#/components/parameters/Cursor"
          },
          {
            "$ref": "#/components/parameters/Limit"
          }
        ],
        "responses": {
          "200": {
            "description": "Repositories currently available to this linked installation.",
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GitHubRepositoryPage"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/actions/repositories": {
      "get": {
        "tags": [
          "actions"
        ],
        "operationId": "listActionsRepositories",
        "x-boxrouter-authority": "read",
        "x-speakeasy-group": "actions.repositories",
        "x-speakeasy-name-override": "list",
        "summary": "Batch Actions enablement and defaults for the given repositories",
        "description": "Requires read authority in the authenticated workspace. Returns one settings\ndocument per requested repository ID, ordered by repository ID: the same\ndocuments `getActionsRepository` serves, each with its ETag beside it instead\nof in a header, so a setup read replaces one request per repository with this\none. A repository with no settings record appears as `exists: false`; omit\nIf-Match on its first write and send its ETag for updates once it exists.\n",
        "parameters": [
          {
            "name": "repository_id",
            "in": "query",
            "required": true,
            "description": "Repositories to read; repeat to select several, for example `repository_id=101&repository_id=202`.",
            "style": "form",
            "explode": true,
            "schema": {
              "type": "array",
              "minItems": 1,
              "maxItems": 250,
              "uniqueItems": true,
              "items": {
                "type": "string",
                "minLength": 1,
                "maxLength": 18,
                "pattern": "^0*[1-9][0-9]*$"
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Per-repository settings documents and their CAS tokens.",
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ActionsRepositoriesResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/actions/repositories/{repository_id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/RepositoryId"
        }
      ],
      "get": {
        "tags": [
          "actions"
        ],
        "operationId": "getActionsRepository",
        "x-boxrouter-authority": "read",
        "x-speakeasy-group": "actions.repositories",
        "x-speakeasy-name-override": "get",
        "summary": "Get Actions enablement and defaults for a repository",
        "description": "Requires read authority in the authenticated workspace. The repository must have\na currently linked, verified GitHub installation. The returned ETag identifies\nthis settings revision. A missing settings record is represented as `exists: false`,\ndisabled with no required policy; it is not silently enabled by reading it. For\n`exists: false`, omit If-Match on the first write; for `exists: true`, send the\nreturned ETag to update the existing record safely.\n",
        "responses": {
          "200": {
            "description": "Workspace-owned settings and safe default state.",
            "headers": {
              "ETag": {
                "description": "Strong settings revision; use it for writes when exists is true.",
                "schema": {
                  "type": "string"
                }
              },
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ActionsRepositorySettings"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "put": {
        "tags": [
          "actions"
        ],
        "operationId": "updateActionsRepository",
        "x-boxrouter-authority": "admin",
        "x-speakeasy-group": "actions.repositories",
        "x-speakeasy-name-override": "update",
        "summary": "Enable or update Actions defaults for a repository",
        "description": "Requires workspace administrator authority. Browser-session calls require the CSRF\ntoken and configured Origin. The minimal enable request is `{\"enabled\":true}`;\nActions creates its safe default settings and begins automatic image preparation\nwithout requiring a named policy, provider key, runner registration or YAML change.\n`policy_id` is optional and, when null, selects the workspace's current safe\ndefaults. When the preceding read returned `exists: false`, omit If-Match to create\nthe settings record; when it returned `exists: true`, send its ETag to update. The\nserver rejects a write if that existence state changed after the read. An\nIdempotency-Key records\nthe logical mutation: identical uncertain retries return the recorded outcome,\nchanged input under the same key conflicts, and unknown effects are reconciled\nwithout automatic redispatch. Disabling stops new admission; it does not cancel\naccepted GitHub workflow runs or change their funding binding.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/CsrfBrowserOnly"
          },
          {
            "name": "If-Match",
            "in": "header",
            "required": false,
            "description": "Required when replacing an existing settings record; omit only to create the default record.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 256,
              "pattern": "^[^\\u0000]*$"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateActionsRepository"
              },
              "examples": {
                "enableWithDefaults": {
                  "summary": "Enable with automatically created safe defaults",
                  "value": {
                    "enabled": true
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Current settings revision; image preparation may still be in progress.",
            "headers": {
              "ETag": {
                "description": "Strong settings revision for the next conditional update.",
                "schema": {
                  "type": "string"
                }
              },
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ActionsRepositorySettings"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/routing/settings": {
      "get": {
        "tags": [
          "routing"
        ],
        "operationId": "getRoutingSettings",
        "x-boxrouter-authority": "read",
        "x-speakeasy-group": "routing",
        "x-speakeasy-name-override": "settings",
        "summary": "Read workspace routing and provider funding",
        "description": "Workspace read authority required. Returns each independently versioned section\nand its opaque ETag in section_etags. Never returns credentials. The GET itself\nhas no whole-document validator; send a chosen section's token in If-Match to\nguard a write to that section.\nOn a workspace's first read, the server atomically creates sections from its\nlegacy funding state. Concurrent first reads return the same persisted sections\nand ETags. Later reads do not change settings unless a supported provider,\nmanaged offer or connected account changed and needs reconciliation; only a\nsection that actually changes advances its ETag. The saved Prevent Overrides\nswitch is retained across reads.\n",
        "responses": {
          "200": {
            "description": "Current settings and section validators.",
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RoutingSettings"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "put": {
        "tags": [
          "routing"
        ],
        "operationId": "updateRoutingSettings",
        "x-boxrouter-authority": "admin",
        "x-speakeasy-group": "routing",
        "x-speakeasy-name-override": "updateSettings",
        "summary": "Update one workspace routing section",
        "description": "Workspace admin (or provider-accounts:manage for provider funding) required;\nbrowser mutations also require Origin and X-CSRF-Token. The body names exactly\none section: routing fields or one provider funding section. Send only the fields\nto change; every omitted field keeps its stored value, and the merged section is\nvalidated as a complete section before it is written. If-Match is optional. When\nsent, it must be the opaque token returned for THAT section by GET or the call\nfails 412 with no write; when omitted, the named fields are written to the\ncurrent section. Atomically update only the named section and advance only its\nETag. A stale token for that same section returns 412 with no write; a concurrent\nRouting edit cannot conflict with provider funding, and edits to distinct\nproviders cannot conflict with one another. Reject duplicate account IDs,\nforeign/wrong-provider accounts and newly enabled Credits on unavailable managed\nproviders before writing. Adding a key does not change provider exclusion.\nIdentical idempotency replay returns the previously recorded response, not a\nsecond write.\n",
        "parameters": [
          {
            "name": "If-Match",
            "in": "header",
            "required": false,
            "description": "Optional opaque ETag for the exact section named in the request body. When sent,\nit must match the section's current token or the call fails 412\nrouting_settings_stale. When omitted, the named fields are written to the\ncurrent section.\n",
            "schema": {
              "type": "string",
              "minLength": 1
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RoutingSettingsUpdate"
              },
              "example": {
                "section": "routing",
                "routing": {
                  "mode": "cheapest"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Current complete settings including updated section validator.",
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RoutingSettings"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "412": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/routing/preview": {
      "get": {
        "tags": [
          "routing"
        ],
        "operationId": "getRoutingPreview",
        "x-boxrouter-authority": "read",
        "x-speakeasy-group": "routing",
        "x-speakeasy-name-override": "preview",
        "summary": "Preview workspace route availability without dispatch",
        "description": "Workspace read authority required. Side-effect-free current eligibility and\nversioned hold quotes from admission. No next-job prediction, workspace spend\ncap or promise that a later create can start. No secret or foreign balance.\n",
        "responses": {
          "200": {
            "description": "Learning state, availability and skipped-route reasons.",
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RoutingPreview"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/actions/readiness": {
      "get": {
        "tags": [
          "actions"
        ],
        "operationId": "getActionsReadiness",
        "x-boxrouter-authority": "read",
        "x-speakeasy-group": "actions",
        "x-speakeasy-name-override": "readiness",
        "summary": "Read Actions runner and workspace funding readiness",
        "description": "Requires workspace read authority. This read-only view uses the workspace's\nexisting provider accounts and credits. Unknown source facts remain unknown;\nlink targets appear only when an existing page can address the reported issue.\nWhen `repository_id` is supplied, readiness is scoped to that repository's saved\nsoftware profile. The profile is resolved from workspace-owned settings; callers\ncannot select a profile through this parameter.\n",
        "parameters": [
          {
            "name": "repository_id",
            "in": "query",
            "required": false,
            "description": "Optional GitHub repository ID whose saved software profile should be checked.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 18,
              "pattern": "^0*[1-9][0-9]*$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Current Actions readiness from workspace evidence.",
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ActionsReadinessResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/actions/runner-catalog": {
      "get": {
        "tags": [
          "actions"
        ],
        "operationId": "getActionsRunnerCatalog",
        "x-boxrouter-authority": "read",
        "x-speakeasy-group": "actions",
        "x-speakeasy-name-override": "runnerCatalog",
        "summary": "Read the recommended Actions runner labels and resource floors",
        "description": "Requires workspace read authority. The catalog is fixed for a server release and does not\ndepend on the workspace, so clients and caches may reuse it until its ETag changes. It does not assert live route availability or\nverified software; use readiness for that. Readiness still carries `runner_catalog` for\nolder clients, but new clients should read this operation instead.\n",
        "responses": {
          "200": {
            "description": "The recommended labels, resource floors and default label.",
            "headers": {
              "ETag": {
                "description": "Strong validator for this catalog; changes only when the catalog changes.",
                "schema": {
                  "type": "string"
                }
              },
              "Cache-Control": {
                "description": "Caching directive; the catalog is private to the caller's session and safe to reuse until revalidated.",
                "schema": {
                  "type": "string"
                }
              },
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ActionsRunnerCatalog"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/actions/policies": {
      "get": {
        "tags": [
          "actions"
        ],
        "operationId": "listActionsPolicies",
        "x-boxrouter-authority": "read",
        "x-speakeasy-group": "actions.policies",
        "x-speakeasy-name-override": "list",
        "summary": "List workspace Actions policies",
        "description": "Requires workspace read authority. Stable ID-ordered pages may be empty; listing never changes policy or starts compute.",
        "parameters": [
          {
            "$ref": "#/components/parameters/Cursor"
          },
          {
            "$ref": "#/components/parameters/Limit"
          }
        ],
        "responses": {
          "200": {
            "description": "Workspace-owned policies; an empty workspace returns an empty page.",
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ActionsPolicyPage"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "post": {
        "tags": [
          "actions"
        ],
        "operationId": "createActionsPolicy",
        "x-boxrouter-authority": "admin",
        "x-speakeasy-group": "actions.policies",
        "x-speakeasy-name-override": "create",
        "summary": "Create a named workspace Actions policy",
        "description": "Requires workspace administrator authority. Browser-session calls require the CSRF\ntoken and configured Origin. Policy settings can only narrow workspace and\nrepository guardrails. The workspace funding choice decides the logical authority\n(workspace BYOK or platform managed); the actual provider, account and payer binding\nis confirmed separately for each attempt and is never taken from a policy. A policy\ncannot change supply or add accounts. Idempotency-Key replays the recorded\noutcome for identical input; changed input conflicts. An unknown outcome is\nreconciled without creating a second policy.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/CsrfBrowserOnly"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateActionsPolicy"
              },
              "example": {
                "name": "fast-builds",
                "settings": {
                  "profile": "linux-basic",
                  "max_runtime_seconds": 900
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created workspace policy and revision.",
            "headers": {
              "ETag": {
                "description": "Strong policy revision for conditional updates.",
                "schema": {
                  "type": "string"
                }
              },
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ActionsPolicy"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/actions/policies/{policy_id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/PolicyId"
        }
      ],
      "get": {
        "tags": [
          "actions"
        ],
        "operationId": "getActionsPolicy",
        "x-boxrouter-authority": "read",
        "x-speakeasy-group": "actions.policies",
        "x-speakeasy-name-override": "get",
        "summary": "Get a workspace Actions policy",
        "description": "Requires workspace read authority. The policy ID is workspace-scoped; foreign and unknown IDs both return 404.",
        "responses": {
          "200": {
            "description": "Policy definition and current revision.",
            "headers": {
              "ETag": {
                "description": "Strong policy revision for conditional updates.",
                "schema": {
                  "type": "string"
                }
              },
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ActionsPolicy"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "put": {
        "tags": [
          "actions"
        ],
        "operationId": "updateActionsPolicy",
        "x-boxrouter-authority": "admin",
        "x-speakeasy-group": "actions.policies",
        "x-speakeasy-name-override": "update",
        "summary": "Replace a workspace Actions policy",
        "description": "Requires workspace administrator authority. Browser-session calls require CSRF and\nthe configured Origin. If-Match is required and must equal the latest ETag. Policy\nchanges only narrow workspace/repository guardrails and do not mutate accepted jobs\nor change their supply, accounts or logical funding authority. Idempotency-Key replays an identical recorded update;\nchanged input conflicts. A stale ETag returns 409 without writing. Unknown outcomes\nare reconciled, never automatically redispatched.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/CsrfBrowserOnly"
          },
          {
            "$ref": "#/components/parameters/IfMatch"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateActionsPolicy"
              },
              "example": {
                "name": "fast-builds",
                "settings": {
                  "profile": "linux-basic",
                  "max_runtime_seconds": 1200
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated policy revision.",
            "headers": {
              "ETag": {
                "description": "Strong policy revision for the next conditional update.",
                "schema": {
                  "type": "string"
                }
              },
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ActionsPolicy"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "delete": {
        "tags": [
          "actions"
        ],
        "operationId": "deleteActionsPolicy",
        "x-boxrouter-authority": "admin",
        "x-speakeasy-group": "actions.policies",
        "x-speakeasy-name-override": "delete",
        "summary": "Delete an unused workspace Actions policy",
        "description": "Requires workspace administrator authority. Browser-session calls require CSRF and\nthe configured Origin. If-Match is required. A policy referenced by repository\ndefaults or accepted work cannot be deleted and returns 409. Idempotency-Key\nreturns the recorded delete result for identical retries; changed input conflicts. Unknown outcomes are\nreconciled without repeating the deletion.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/CsrfBrowserOnly"
          },
          {
            "$ref": "#/components/parameters/IfMatch"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "204": {
            "description": "Policy removed; referenced policies are refused with 409.",
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/actions/preview": {
      "post": {
        "tags": [
          "actions"
        ],
        "operationId": "previewActions",
        "x-boxrouter-authority": "read",
        "x-speakeasy-group": "actions",
        "x-speakeasy-name-override": "preview",
        "summary": "Preview Actions label and policy eligibility",
        "description": "Requires read authority for the linked repository in the authenticated workspace.\nThis is a read-only evaluation of the same resolved policy and route matcher used\nfor dispatch. It creates no runner, sandbox, reservation or billing hold. Refused\nand unknown results remain explicit; the preview never relaxes a requirement or\nclaims an unverified route is eligible. It does not verify runner images. Runner image readiness is checked separately before dispatch.\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ActionsPreviewRequest"
              },
              "example": {
                "repository_id": "303"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Resolved eligibility, including an explicit refusal or unknown result.",
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ActionsPreviewResult"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/actions/runs": {
      "get": {
        "tags": [
          "actions"
        ],
        "operationId": "listActionsRuns",
        "x-boxrouter-authority": "read",
        "x-speakeasy-group": "actions.runs",
        "x-speakeasy-name-override": "list",
        "summary": "List workspace Actions workflow-run projections",
        "description": "Requires workspace read authority. Pages may be empty and default to newest-first\nby creation time; `sort` also supports oldest-first by creation time and longest\nfirst by duration. Equal sort values retain a stable run ID order, including\nacross pages. A run's status and cost are BoxRouter's latest recorded evidence;\nthis read does not poll GitHub, change a run, start a job or retry an uncertain\neffect.\n",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": false,
            "description": "Search text, case-insensitive. Matches the workflow name, repository name, branch, a\ncommit SHA prefix, or a run number written as `42` or `#42`.\n",
            "schema": {
              "$ref": "#/components/schemas/ActionsRunFilterText"
            }
          },
          {
            "name": "repository_id",
            "in": "query",
            "required": false,
            "description": "Repository ID; repeat to select several (OR).",
            "style": "form",
            "explode": true,
            "schema": {
              "type": "array",
              "minItems": 1,
              "maxItems": 50,
              "uniqueItems": true,
              "items": {
                "type": "string",
                "minLength": 1,
                "maxLength": 128,
                "pattern": "^[A-Za-z0-9_.:-]+$"
              }
            }
          },
          {
            "name": "state",
            "in": "query",
            "required": false,
            "description": "Run state, or for an ended run its result status (`succeeded`, `failed`, `cancelled`, `skipped`, `neutral`);\nrepeat to select several (OR), for example `state=running&state=queued`.\n",
            "style": "form",
            "explode": true,
            "schema": {
              "type": "array",
              "minItems": 1,
              "maxItems": 50,
              "uniqueItems": true,
              "items": {
                "$ref": "#/components/schemas/ActionsRunStateFilter"
              }
            }
          },
          {
            "name": "workflow",
            "in": "query",
            "required": false,
            "description": "Workflow name; repeat to select several (OR). Values come from the facets.",
            "style": "form",
            "explode": true,
            "schema": {
              "$ref": "#/components/schemas/ActionsRunFilterValues"
            }
          },
          {
            "name": "branch",
            "in": "query",
            "required": false,
            "description": "Branch name; repeat to select several (OR).",
            "style": "form",
            "explode": true,
            "schema": {
              "$ref": "#/components/schemas/ActionsRunFilterValues"
            }
          },
          {
            "name": "triggered_by",
            "in": "query",
            "required": false,
            "description": "GitHub login of the triggering actor, bots included (`dependabot[bot]`); repeat for several (OR).",
            "style": "form",
            "explode": true,
            "schema": {
              "$ref": "#/components/schemas/ActionsRunFilterValues"
            }
          },
          {
            "name": "job",
            "in": "query",
            "required": false,
            "description": "A job selection as unpadded base64url-encoded UTF-8 JSON `[workflow, job]`; facet labels remain `Workflow › job`. A run matches when it has any given job. Repeat for several (OR).",
            "style": "form",
            "explode": true,
            "schema": {
              "$ref": "#/components/schemas/ActionsRunFilterValues"
            }
          },
          {
            "name": "runner_label",
            "in": "query",
            "required": false,
            "description": "A requested runner label; a run matches when any job requested any given label. Repeat for several (OR).",
            "style": "form",
            "explode": true,
            "schema": {
              "$ref": "#/components/schemas/ActionsRunFilterValues"
            }
          },
          {
            "name": "sort",
            "in": "query",
            "required": false,
            "description": "`newest` (default) or `oldest` by creation, or `longest` by duration from first start to\nend; runs without a duration (active, or end not confirmed) come last. A `next_cursor`\ncontinues the same filters and sort.\n",
            "schema": {
              "type": "string",
              "enum": [
                "newest",
                "oldest",
                "longest"
              ],
              "default": "newest"
            }
          },
          {
            "$ref": "#/components/parameters/Cursor"
          },
          {
            "$ref": "#/components/parameters/Limit"
          }
        ],
        "responses": {
          "200": {
            "description": "Workspace-owned workflow runs; an empty workspace returns an empty page.",
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ActionsRunPage"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/actions/runs/facets": {
      "get": {
        "tags": [
          "actions"
        ],
        "operationId": "listActionsRunFacets",
        "x-boxrouter-authority": "read",
        "x-speakeasy-group": "actions.runs",
        "x-speakeasy-name-override": "listFacets",
        "summary": "Count the values each run filter offers",
        "description": "For each filter of `listActionsRuns`, its values with the number of runs in the whole\nworkspace that have the value, ignoring any active filters. A run counts once for each\nvalue it has. Requires workspace read authority; it does not poll GitHub.\n",
        "responses": {
          "200": {
            "description": "Filter values and counts.",
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ActionsRunFacets"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/actions/pool-idle-time": {
      "get": {
        "tags": [
          "actions"
        ],
        "operationId": "getActionsPoolIdleTime",
        "x-boxrouter-authority": "read",
        "x-speakeasy-group": "actions.poolIdleTime",
        "x-speakeasy-name-override": "get",
        "summary": "Get the billed time of runners that served no job",
        "description": "Requires workspace read authority. A pooled runner can cost money while no GitHub job\nshows it: it sat idle until the pool drained it, or its pickup was foreign or revoked,\nor it failed after its sandbox existed. That time is charged to the payer and shown\nhere, apart from every run and job. The read counts the runners that started in\n`[since, until)`, in total and per pool, with the same `billing` object a run carries.\n`idle_seconds` is each runner's lifetime from creation to its end (to now for a runner\nthat is still alive). `until` defaults to now, `since` to 30 days before `until`, and the\nrange may not exceed 92 days; a longer or empty range returns 400. It does not poll\nGitHub or a provider and does not change a runner.\n",
        "parameters": [
          {
            "name": "since",
            "in": "query",
            "required": false,
            "description": "Start of the range, inclusive.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "until",
            "in": "query",
            "required": false,
            "description": "End of the range, exclusive.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Idle runner time and its billing for the range.",
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ActionsPoolIdleTimeReport"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/actions/runs/{run_id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/RunId"
        }
      ],
      "get": {
        "tags": [
          "actions"
        ],
        "operationId": "getActionsRun",
        "x-boxrouter-authority": "read",
        "x-speakeasy-group": "actions.runs",
        "x-speakeasy-name-override": "get",
        "summary": "Get a workflow-run projection and aggregate billing evidence",
        "description": "Requires workspace read authority. Foreign and unknown run IDs both return 404; state and costs are not inferred from missing observations.",
        "responses": {
          "200": {
            "description": "Latest recorded workflow-run state and billing projection.",
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ActionsRun"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/actions/runs/{run_id}/jobs": {
      "parameters": [
        {
          "$ref": "#/components/parameters/RunId"
        }
      ],
      "get": {
        "tags": [
          "actions"
        ],
        "operationId": "listActionsRunJobs",
        "x-boxrouter-authority": "read",
        "x-speakeasy-group": "actions.runs",
        "x-speakeasy-name-override": "list_jobs",
        "summary": "List GitHub jobs projected for a workflow run",
        "description": "Requires workspace read authority. Job assignment is tied to the runner GitHub actually assigns, not the job a JIT label initially requested.",
        "parameters": [
          {
            "$ref": "#/components/parameters/Cursor"
          },
          {
            "$ref": "#/components/parameters/Limit"
          }
        ],
        "responses": {
          "200": {
            "description": "Workspace-owned job projections; an empty run returns an empty page.",
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ActionsJobPage"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/actions/runs/{run_id}/placements": {
      "parameters": [
        {
          "$ref": "#/components/parameters/RunId"
        }
      ],
      "get": {
        "tags": [
          "actions"
        ],
        "operationId": "listActionsRunPlacements",
        "x-boxrouter-authority": "read",
        "x-speakeasy-group": "actions.runs",
        "x-speakeasy-name-override": "list_placements",
        "summary": "List placements attempted for a workflow run",
        "description": "Requires workspace read authority. Placement state, outcome, cleanup and billing evidence remain separate; uncertain effects are never replayed by this read.",
        "parameters": [
          {
            "$ref": "#/components/parameters/Cursor"
          },
          {
            "$ref": "#/components/parameters/Limit"
          }
        ],
        "responses": {
          "200": {
            "description": "Workspace-owned placement history; an empty run returns an empty page.",
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ActionsPlacementPage"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/actions/jobs/{job_id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/JobId"
        }
      ],
      "get": {
        "tags": [
          "actions"
        ],
        "operationId": "getActionsJob",
        "x-boxrouter-authority": "read",
        "x-speakeasy-group": "actions.jobs",
        "x-speakeasy-name-override": "get",
        "summary": "Get an Actions job projection",
        "description": "Requires workspace read authority. The GitHub assignment is authoritative; a requested job ID is not treated as runner reservation.",
        "responses": {
          "200": {
            "description": "Latest workspace-owned job projection and linked placement IDs.",
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ActionsJob"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/actions/jobs/{job_id}/steps": {
      "parameters": [
        {
          "$ref": "#/components/parameters/JobId"
        }
      ],
      "get": {
        "tags": [
          "actions"
        ],
        "operationId": "getActionsJobSteps",
        "x-boxrouter-authority": "execute",
        "x-speakeasy-group": "actions.jobs",
        "x-speakeasy-name-override": "getSteps",
        "summary": "Get GitHub workflow steps for an Actions job",
        "description": "Requires workspace execute authority. Resolves the selected workspace-owned\njob and its exact historical run attempt before reading the assigned GitHub\nworkflow job. Steps preserve GitHub source order and original step numbers;\nposition is the zero-based display order. Pending, unavailable, forbidden and\nremoved are explicit source states. Step output is not included.\n",
        "responses": {
          "200": {
            "description": "Current GitHub workflow step metadata for the selected job.",
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ActionsJobSteps"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/actions/jobs/{job_id}/logs": {
      "parameters": [
        {
          "$ref": "#/components/parameters/JobId"
        }
      ],
      "get": {
        "tags": [
          "actions"
        ],
        "operationId": "getActionsJobLogs",
        "x-boxrouter-authority": "execute",
        "x-speakeasy-group": "actions.jobs",
        "x-speakeasy-name-override": "getLogs",
        "summary": "Read a bounded prefix of the selected GitHub job log",
        "description": "Requires workspace execute authority. Resolves the workspace-owned job,\ncurrent repository binding, assigned GitHub job and exact historical attempt\nbefore fetching only that native whole-job log. At most 1 MiB is returned;\npartial indicates a bounded prefix. Output is transient and is not retained.\nIndividual step log availability depends on the GitHub App/repository source.\n",
        "responses": {
          "200": {
            "description": "Selected whole-job log prefix or an explicit source availability state.",
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ActionsJobLogs"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/actions/jobs/{job_id}/steps/{step_position}/logs": {
      "parameters": [
        {
          "$ref": "#/components/parameters/JobId"
        },
        {
          "name": "step_position",
          "in": "path",
          "required": true,
          "description": "Zero-based position in the selected fresh GitHub job's steps array.",
          "schema": {
            "type": "integer",
            "minimum": 0
          }
        }
      ],
      "get": {
        "tags": [
          "actions"
        ],
        "operationId": "getActionsJobStepLogs",
        "x-boxrouter-authority": "execute",
        "x-speakeasy-group": "actions.jobs",
        "x-speakeasy-name-override": "getStepLogs",
        "summary": "Read a bounded prefix of one GitHub step log",
        "description": "Requires workspace execute authority. step_position is zero-based and is\nverified against the selected fresh GitHub job before this endpoint is read.\nGitHub may report individual step logs unavailable for an App/repository;\nthis is returned explicitly without synthesizing output from the whole-job log.\nAt most 1 MiB is returned and partial indicates a bounded prefix.\n",
        "responses": {
          "200": {
            "description": "Selected step log prefix or an explicit source availability state.",
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ActionsJobLogs"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/actions/jobs/{job_id}/events": {
      "parameters": [
        {
          "$ref": "#/components/parameters/JobId"
        }
      ],
      "get": {
        "tags": [
          "actions"
        ],
        "operationId": "getActionsJobEvents",
        "x-boxrouter-authority": "execute",
        "x-speakeasy-group": "actions.jobs",
        "x-speakeasy-name-override": "listEvents",
        "summary": "List Actions step events for a job",
        "parameters": [
          {
            "$ref": "#/components/parameters/Cursor"
          },
          {
            "$ref": "#/components/parameters/Limit"
          }
        ],
        "description": "Requires workspace execute authority. Returns durable step events recorded for\nthis workspace-owned Actions job, ordered by event time and ID. Use the\ncontinuation cursor to retrieve the next page; the list is empty when no\nevents are available.\n",
        "responses": {
          "200": {
            "description": "Workspace-scoped page of step events for the job, in ascending event order.",
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ActionsJobEventPage"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/actions/placements/{placement_id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/PlacementId"
        }
      ],
      "get": {
        "tags": [
          "actions"
        ],
        "operationId": "getActionsPlacement",
        "x-boxrouter-authority": "read",
        "x-speakeasy-group": "actions.placements",
        "x-speakeasy-name-override": "get",
        "summary": "Get an Actions placement and its cost and cleanup evidence",
        "description": "Requires workspace read authority. A completed workflow job does not prove sandbox cleanup or final charge; pending and unknown remain explicit.",
        "responses": {
          "200": {
            "description": "Latest recorded placement state, actual assignment, billing and cleanup evidence.",
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ActionsPlacement"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/actions/runs/{run_id}/cancel": {
      "parameters": [
        {
          "$ref": "#/components/parameters/RunId"
        }
      ],
      "post": {
        "tags": [
          "actions"
        ],
        "operationId": "cancelActionsRun",
        "x-boxrouter-authority": "execute",
        "x-speakeasy-group": "actions.runs",
        "x-speakeasy-name-override": "cancel",
        "summary": "Ask GitHub to cancel the entire workflow run",
        "description": "Requires workspace execute authority. This explicitly cancels the whole GitHub\nworkflow run, including its other jobs; it cannot cancel only one job. GitHub\nremains authoritative for cancellation. A 202 means GitHub acknowledged the\nrequest, not that every job or sandbox has ended. Idempotency-Key identifies this\nuser-authorized mutation. An identical replay returns the recorded result; changed\ninput conflicts. Unknown outcomes are reconciled against GitHub without repeating\nthe cancellation automatically. BoxRouter never cancels as a side effect of a\nread, timeout or cleanup failure.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/CsrfBrowserOnly"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "202": {
            "description": "Whole-workflow cancellation request accepted by GitHub; completion remains separately observed.",
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ActionsRunControlResult"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/actions/runs/{run_id}/rerun": {
      "parameters": [
        {
          "$ref": "#/components/parameters/RunId"
        }
      ],
      "post": {
        "tags": [
          "actions"
        ],
        "operationId": "rerunActionsRun",
        "x-boxrouter-authority": "execute",
        "x-speakeasy-group": "actions.runs",
        "x-speakeasy-name-override": "rerun",
        "summary": "Ask GitHub to rerun the entire workflow",
        "description": "Requires workspace execute authority. This explicitly asks GitHub to rerun the\nentire workflow run, not one job or only failed jobs. GitHub creates and owns the\nnew attempt. A 202 means GitHub acknowledged the request; it does not mean the new\njobs have started. Idempotency-Key identifies this user-authorized mutation. An\nidentical replay returns the recorded result; changed input conflicts. An unknown\noutcome is reconciled against GitHub and never automatically submitted again.\nActions admission still rechecks repository binding, policy, trust and the\nimmutable workspace/account/payer before creating any new placement.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/CsrfBrowserOnly"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "202": {
            "description": "Whole-workflow rerun accepted by GitHub; the next attempt is observed separately.",
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ActionsRunControlResult"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/actions/runs/{run_id}/rerun-failed-jobs": {
      "parameters": [
        {
          "$ref": "#/components/parameters/RunId"
        }
      ],
      "post": {
        "tags": [
          "actions"
        ],
        "operationId": "rerunActionsRunFailedJobs",
        "x-boxrouter-authority": "execute",
        "x-speakeasy-group": "actions.runs",
        "x-speakeasy-name-override": "rerunFailedJobs",
        "summary": "Ask GitHub to rerun failed jobs and their dependents",
        "description": "Requires workspace execute authority. This explicitly asks GitHub to rerun the failed\njobs of the entire workflow run and the jobs that depend on them in a new attempt.\nPassed jobs rerun only when they depend on a failed job. GitHub creates and owns the new attempt. A 202 means\nGitHub acknowledged the request; it does not mean the new jobs have started.\nIdempotency-Key identifies this user-authorized mutation. An identical replay returns\nthe recorded result; changed input conflicts. An unknown outcome is reconciled against\nGitHub and never automatically submitted again. A run with no failed job is refused\nwith 409. Actions admission still rechecks repository binding, policy, trust and the\nimmutable workspace/account/payer before creating any new placement.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/CsrfBrowserOnly"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "202": {
            "description": "Failed-jobs rerun accepted by GitHub; the next attempt is observed separately.",
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ActionsRunControlResult"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/operations": {
      "get": {
        "tags": [
          "operations"
        ],
        "operationId": "listOperations",
        "x-speakeasy-group": "operations",
        "x-speakeasy-name-override": "list",
        "summary": "List recorded workspace operations",
        "description": "Stable ID-ordered pagination over authoritative mutation records. Observed time is the lookup time, not the original execution timestamp. Listing never reconciles or retries work. `sandbox_id` and `label` keep only operations whose sandbox is that ID or carries every given label, so the operations behind a labelled batch of sandboxes take one filtered list instead of paging through the workspace; a create that never made a sandbox has none to match. Unknown or repeated parameters fail the request (`label` may repeat). A request refused before anything was reserved (its error reply says `outcome: not_started` and carries `operation_id: null`) leaves no operation; its reply's `request_id`, `code` and `outcome` are the record of the attempt.",
        "parameters": [
          {
            "$ref": "#/components/parameters/Cursor"
          },
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "name": "sandbox_id",
            "in": "query",
            "description": "Only operations on this sandbox.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 128,
              "pattern": "^[^\\u0000]*$"
            }
          },
          {
            "name": "label",
            "in": "query",
            "description": "A label the sandbox must carry: key=value matches that exact value (the value may be empty), and a bare key matches any value. Repeat for labels that must all match.",
            "style": "form",
            "explode": true,
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "pattern": "^[^=]+(=.*)?$"
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Owned operation records.",
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data",
                    "next_cursor"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Operation"
                      }
                    },
                    "next_cursor": {
                      "type": [
                        "string",
                        "null"
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/artifacts": {
      "post": {
        "tags": [
          "artifacts"
        ],
        "operationId": "uploadArtifact",
        "x-speakeasy-group": "artifacts",
        "x-speakeasy-name-override": "upload",
        "summary": "Upload a staged input",
        "description": "Stream opaque source bytes to workspace-scoped temporary storage. Enforce\nworkspace upload quotas without buffering the entire request in memory.\nCompute the digest server-side; return a handle only after the full upload\nsucceeds. A failed upload is not a usable artifact. Do not execute or import\nuploaded code. Artifact references stay workspace-scoped and can be used across routes.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/octet-stream": {
              "schema": {
                "type": "string",
                "format": "binary"
              },
              "example": "build output\n"
            }
          }
        },
        "responses": {
          "201": {
            "description": "Complete staged artifact and its retention deadline.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Artifact"
                }
              }
            }
          },
          "413": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/artifacts/{artifact_id}": {
      "parameters": [
        {
          "name": "artifact_id",
          "in": "path",
          "required": true,
          "description": "Workspace-owned artifact ID.",
          "schema": {
            "type": "string",
            "minLength": 1
          }
        }
      ],
      "get": {
        "tags": [
          "artifacts"
        ],
        "operationId": "getArtifact",
        "x-speakeasy-group": "artifacts",
        "x-speakeasy-name-override": "get",
        "summary": "Inspect a staged artifact",
        "description": "Return metadata only. Unknown, unowned and expired artifacts return 404.",
        "responses": {
          "200": {
            "description": "Artifact size, digest and retention deadline.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Artifact"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "delete": {
        "tags": [
          "artifacts"
        ],
        "operationId": "deleteArtifact",
        "x-speakeasy-group": "artifacts",
        "x-speakeasy-name-override": "delete",
        "summary": "Remove a staged artifact",
        "description": "Delete source storage without deleting resulting provider images. Reject with\n409 while a submitted build, file transfer or credential-factory activation\nstill needs these bytes. An activated factory uses its retained encrypted\ncopy; deleting staging bytes does not revoke that credential version. Successful deletion is\nidempotent for a known owned record; unowned IDs remain 404.\n",
        "responses": {
          "204": {
            "description": "Artifact bytes removed."
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/images/prepare": {
      "post": {
        "tags": [
          "images"
        ],
        "operationId": "prepareImage",
        "x-speakeasy-group": "images",
        "x-speakeasy-name-override": "prepare",
        "summary": "Prepare an image on selected providers",
        "description": "Start background preparation using this workspace's payer-account rules, on the named\n`providers` or on the `top` providers a create with the `match` body would pick now.\nA named provider that cannot run the image reports its fit reason immediately; a\n`match` body that no route can run is refused as that create would be. With `match`,\nthe response lists the picked providers in rank order, and each reason says how it\nwas ranked. A ready result means a usable copy existed when preparation completed;\nit does not keep the copy awake afterward. Read progress from GET /images/preparations.\nOCI and Dockerfile inputs use the same declared preparation capabilities as a create.\nA Dockerfile response returns a content selector for status and unprepare. If no selected\noffering declares prepared Dockerfile/context support, it is refused before reading the\ncontext or starting provider work. Existing provider artifacts are already prepared.\nThe request JSON is limited to 64 KiB; uploaded contexts retain the artifacts API limits.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PrepareImage"
              },
              "example": {
                "match": {
                  "image": "python:3.13-slim"
                },
                "top": 2
              }
            }
          }
        },
        "responses": {
          "202": {
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "description": "Preparation started or already in progress.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ImagePreparationStatus"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/images/preparations": {
      "get": {
        "tags": [
          "images"
        ],
        "operationId": "getImagePreparations",
        "x-speakeasy-group": "images",
        "x-speakeasy-name-override": "status",
        "summary": "Read image preparation status",
        "description": "Reads preparation state recorded for the requested image in this workspace. The providers query can limit the result; omitted returns every recorded provider. A content selector reads the workspace's recorded copy without contacting a registry.",
        "parameters": [
          {
            "name": "image",
            "description": "Image reference, `repo@sha256:digest`, or a Dockerfile preparation's returned\n`sha256:<64 lowercase hex>` selector. Content selectors read only this workspace's\nrecorded copies without contacting a registry. A private tag works when this workspace has\nprepared or created it with registry_credentials before; otherwise name its digest.\n",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "providers",
            "in": "query",
            "required": false,
            "description": "Limit the status to these providers; omitted returns all recorded providers.",
            "schema": {
              "type": "array",
              "minItems": 1,
              "uniqueItems": true,
              "items": {
                "type": "string",
                "minLength": 1
              }
            },
            "style": "form",
            "explode": true
          }
        ],
        "responses": {
          "200": {
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "description": "Current preparation state for the workspace's recorded provider copies.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ImagePreparationStatus"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/images/unprepare": {
      "post": {
        "tags": [
          "images"
        ],
        "operationId": "unprepareImage",
        "x-speakeasy-group": "images",
        "x-speakeasy-name-override": "unprepare",
        "summary": "Remove this workspace's prepared image copies",
        "description": "Remove only copies Cloud recorded for this workspace. Copies on managed accounts\nthat other workspaces still use remain available, while this workspace's use is\ndropped. The image itself is not deleted. A provider reports gone only after it\nconfirms removal. A later sandbox create may prepare the image again.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UnprepareImage"
              },
              "example": {
                "image": "python:3.13-slim",
                "providers": "all"
              }
            }
          }
        },
        "responses": {
          "200": {
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "description": "Removal outcome per selected provider.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ImagePreparationStatus"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/sandboxes/{sandbox_id}/processes": {
      "parameters": [
        {
          "$ref": "#/components/parameters/SandboxId"
        }
      ],
      "post": {
        "tags": [
          "processes"
        ],
        "operationId": "startProcess",
        "x-speakeasy-group": "processes",
        "x-speakeasy-name-override": "start",
        "summary": "Start a durable background command",
        "description": "Runs a command in the background in a Bash login shell and returns a process ID. The\nprocess keeps running between your calls: read its output, write to its input, or cancel\nit later, from any client. The sandbox's lifetime bounds how long it can run; cancel it to\nend it sooner.\n\nThe sandbox image needs Linux `/proc`, Bash, and a few standard tools (`setsid`, `nohup`,\n`tail`, `base64`). If one is missing, the call fails with `unsupported_feature` before\nanything starts.\n\n`stdin` defaults to `false`. Setting it to `true`, to write to the process later, needs a\nsandbox created with the `processes.input` requirement and a route that supports writing to\nthe process after it reconnects (`reattached_stdin`). To check ahead of time which routes\nqualify, send the same requirements to `POST /sandboxes/match`.\n\nWith `wait_for_port`, the call returns once that port accepts TCP connections inside the\nsandbox. If the process exits first, or the port is still closed after 30 seconds, the\nprocess is ended and the call fails with `409 port_not_listening`. `details` carries\n`port`, `stdout_tail`, `stderr_tail` and, when the process exited, `exit_code`.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/StartProcess"
              },
              "example": {
                "command": "python3 -m http.server 3000",
                "wait_for_port": 3000
              }
            }
          }
        },
        "responses": {
          "201": {
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "description": "Durable process handle created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Process"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/sandboxes/{sandbox_id}/processes/{process_id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/SandboxId"
        },
        {
          "$ref": "#/components/parameters/ProcessId"
        }
      ],
      "get": {
        "tags": [
          "processes"
        ],
        "operationId": "readProcess",
        "x-speakeasy-group": "processes",
        "x-speakeasy-name-override": "read",
        "summary": "Read process output from byte offsets",
        "description": "**Process observation**\n\nYou can rely on:\n- A completed result carries the exact exit status and the complete output; otherwise the call reports lost observation or incomplete output.\n- Output bytes are exact on every route (commands in byte mode stay exact everywhere).\n\nYou can set: observation deadline. Reattach where the route supports it.\n\nNot promised: chunk sizes; immediate status visibility; output kept beyond the retained history.\n\n**Process wait**\n\nYou can rely on:\n- Returns the exact observed exit status.\n- An observation deadline does not claim the process stopped.\n\nYou can set: observation deadline.\n\nReturns up to 256 KiB per stream from the requested byte offsets. Pass the\nreturned next offsets to continue without gaps or repeats. `exit_code` is set\nonly after the process ended and both streams were read to their ends. Reads\nare non-blocking. If the provider replaced the guest session, the answer is\n410 `expired`; the command is never run again.\n",
        "parameters": [
          {
            "name": "stdout",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            }
          },
          {
            "name": "stderr",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            }
          }
        ],
        "responses": {
          "200": {
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "description": "Retained output starting at the given offsets.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProcessOutput"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "410": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "delete": {
        "tags": [
          "processes"
        ],
        "operationId": "removeProcess",
        "x-speakeasy-group": "processes",
        "x-speakeasy-name-override": "remove",
        "summary": "Delete a finished process's retained output",
        "description": "Deletes the retained output and metadata for a finished process in the addressed sandbox. It does not stop a running process; that request returns 409. The SDK generates an Idempotency-Key when omitted; reuse a supplied key with the identical request to reconcile an uncertain result.",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "204": {
            "description": "Removed.",
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "410": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/sandboxes/{sandbox_id}/processes/{process_id}/stdin": {
      "parameters": [
        {
          "$ref": "#/components/parameters/SandboxId"
        },
        {
          "$ref": "#/components/parameters/ProcessId"
        }
      ],
      "post": {
        "tags": [
          "processes"
        ],
        "operationId": "writeProcessStdin",
        "x-speakeasy-group": "processes",
        "x-speakeasy-name-override": "write_stdin",
        "summary": "Write process input",
        "description": "You can rely on:\n- Input is delivered in order.\n- EOF is explicit.\n- Uncertain delivery is never resent.\n- Input is UTF-8 text on every route.\n\nYou can set: data (text), EOF.\n\nNot promised: chunking on the wire.\n\nAppend text to a process started with `stdin: true`. Calls from one client\nmust be awaited sequentially to preserve input order. The selected route must\nsupport both `processes.input` and input after process reconnection\n(`reattached_stdin`); otherwise writes and EOF are refused as `unsupported_feature`\nbefore dispatch. Use `POST /sandboxes/match` with `requirements.processes.input`\nset to true to inspect eligible routes before create. If stdin is closed, return 409.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WriteStdin"
              },
              "example": {
                "data": "yes\n"
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "Input accepted by the provider; application consumption is not guaranteed.",
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "410": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/sandboxes/{sandbox_id}/processes/{process_id}/stdin/close": {
      "parameters": [
        {
          "$ref": "#/components/parameters/SandboxId"
        },
        {
          "$ref": "#/components/parameters/ProcessId"
        }
      ],
      "post": {
        "tags": [
          "processes"
        ],
        "operationId": "closeProcessStdin",
        "x-speakeasy-group": "processes",
        "x-speakeasy-name-override": "close_stdin",
        "summary": "Send stdin EOF",
        "description": "You can rely on:\n- Input is delivered in order.\n- EOF is explicit.\n- Uncertain delivery is never resent.\n- Input is UTF-8 text on every route.\n\nYou can set: data (text), EOF.\n\nNot promised: chunking on the wire.\n\nClose only the input stream of a process started with stdin enabled; unsupported providers refuse before dispatch.\n",
        "responses": {
          "204": {
            "description": "Stdin closure confirmed.",
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "410": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/sandboxes/{sandbox_id}/processes/{process_id}/cancel": {
      "parameters": [
        {
          "$ref": "#/components/parameters/SandboxId"
        },
        {
          "$ref": "#/components/parameters/ProcessId"
        }
      ],
      "post": {
        "tags": [
          "processes"
        ],
        "operationId": "cancelProcess",
        "x-speakeasy-group": "processes",
        "x-speakeasy-name-override": "cancel",
        "summary": "Cancel a durable process",
        "description": "Ends the process and everything it started. This works on every sandbox; it needs no\n`processes.cancel` requirement. Cancelling a process that has already finished succeeds and\nchanges nothing.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "204": {
            "description": "Cancellation acknowledged, or process already exited.",
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "410": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/credits": {
      "get": {
        "tags": [
          "credits"
        ],
        "operationId": "getCredits",
        "x-speakeasy-group": "credits",
        "x-speakeasy-name-override": "balance",
        "summary": "Get the workspace credit balance",
        "description": "Requires account-management permission; execution keys receive 403. Returns 503\npayments_unavailable while credit purchases are not configured. BYOK work never\ndepends on this balance.\n",
        "responses": {
          "200": {
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "description": "Authoritative ledger balance and accepted top-up bounds.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreditBalance"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/spend-limits": {
      "get": {
        "tags": [
          "spend-limits"
        ],
        "operationId": "listSpendLimits",
        "x-speakeasy-group": "spend_limits",
        "x-speakeasy-name-override": "list",
        "summary": "List managed-compute spend limits",
        "description": "Requires account-management permission; execution keys receive 403. Returns the\nworkspace cap and every key's cap; a scope with no cap has `spend_limit: null`.\nEach capped scope also carries `spent` so far in its current period, holds included:\n`workspace_spent_nanodollars` for the workspace and `spent_nanodollars` per key.\nLimits and usage are scoped to the configured test or live billing book. BYOK usage\nis excluded.\n",
        "responses": {
          "200": {
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "description": "The workspace cap.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SpendLimitList"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/spend-limits/{scope}": {
      "parameters": [
        {
          "name": "scope",
          "in": "path",
          "required": true,
          "description": "What the cap applies to. Only `workspace` exists: it covers every API key in the\nworkspace. Any other value returns 400 `invalid_request` with `details.field` `scope`.\n",
          "schema": {
            "type": "string",
            "enum": [
              "workspace"
            ]
          }
        }
      ],
      "put": {
        "tags": [
          "spend-limits"
        ],
        "operationId": "setSpendLimit",
        "x-speakeasy-group": "spend_limits",
        "x-speakeasy-name-override": "set",
        "summary": "Set a managed-compute spend cap",
        "description": "Requires account-management permission. The cap applies to the scope's settled\nmanaged charges and open managed holds. `limit_period` sets when it resets: `daily`\nand `monthly` at 00:00 UTC (monthly on the first of the month), `total` never.\nReplaces any cap the scope already has. BYOK usage is excluded.\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SpendLimit"
              },
              "example": {
                "limit_usd": "25.00",
                "limit_period": "monthly"
              }
            }
          }
        },
        "responses": {
          "200": {
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "description": "The scope's cap after replacement.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SpendLimitRecord"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "delete": {
        "tags": [
          "spend-limits"
        ],
        "operationId": "clearSpendLimit",
        "x-speakeasy-group": "spend_limits",
        "x-speakeasy-name-override": "clear",
        "summary": "Clear a managed-compute spend cap",
        "description": "Requires account-management permission. Removes the scope's cap. Clearing a scope\nwith no cap succeeds and returns `spend_limit: null`.\n",
        "responses": {
          "200": {
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "description": "The scope with no cap.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SpendLimitRecord"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/credits/purchases": {
      "post": {
        "tags": [
          "credits"
        ],
        "operationId": "createCreditPurchase",
        "x-speakeasy-group": "credits",
        "x-speakeasy-name-override": "purchase",
        "summary": "Start a credit purchase through Checkout or a saved card",
        "description": "Without payment_method_id, records a pending purchase and returns the hosted\nCheckout page; success_url and cancel_url are required for this path. The response\nreports fee_minor and total_minor before redirect: Checkout charges total_minor\n(amount_minor plus BoxRouter's purchase fee, before tax) in two line items, and only\namount_minor is added as credit. A refund returns credit only; the fee is not\nrefunded. With a\nworkspace-owned payment_method_id, creates and pays a\nStripe invoice using that card. A verified paid invoice returns confirmed; when\npayer authentication is required, returns pending with the hosted invoice\nauthentication_url. Send the payer there, then poll this purchase after they\nreturn to the dashboard. Credit is added only after BoxRouter fetches and validates\nthe paid invoice. A definitive card decline returns payment_declined with the\npurchase ID and a short safe decline reason in error details, outcome not_started;\nthe failed purchase remains in history. Repeating a request with the same\nIdempotency-Key returns its original result; a different amount or card under that\nkey is a 409. After a payment_provider_unavailable response with outcome unknown,\nretry with the same key.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/RequiredIdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateCreditPurchase"
              },
              "example": {
                "amount_minor": 2500,
                "payment_method_id": "pm_1Example",
                "expected_total_minor": 2500
              }
            }
          }
        },
        "responses": {
          "201": {
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "description": "Checkout purchase, saved-card purchase awaiting authentication, or saved-card purchase confirmed paid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreatedCreditPurchase"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "description": "The saved-card charge was declined and its failed purchase is retained.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreditPurchaseDeclined"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "get": {
        "tags": [
          "credits"
        ],
        "operationId": "listCreditPurchases",
        "x-speakeasy-group": "credits",
        "x-speakeasy-name-override": "purchases",
        "summary": "List recent credit purchases",
        "description": "Workspace-owned purchases in every state, ordered by creation time and ID descending. Invoice and receipt links appear only after confirmed payment. New purchases do not shift subsequent pages. Invalid or another workspace's cursor is a 400.",
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Cursor"
          }
        ],
        "responses": {
          "200": {
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "description": "Purchase page, newest first; next_cursor is null at the end.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreditPurchaseList"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/credits/purchases/quote": {
      "post": {
        "tags": [
          "credits"
        ],
        "operationId": "quoteCreditPurchase",
        "x-speakeasy-group": "credits",
        "x-speakeasy-name-override": "quote_purchase",
        "summary": "Preview a credit purchase and its tax",
        "description": "Returns Stripe's current tax preview for the requested top-up amount. Requires account-management permission and is available only when in-page card purchases are enabled.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreditPurchaseQuoteRequest"
              },
              "example": {
                "amount_minor": 2500
              }
            }
          }
        },
        "responses": {
          "200": {
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "description": "Current purchase and tax quote.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreditPurchaseQuote"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/credits/usage": {
      "get": {
        "tags": [
          "credits"
        ],
        "operationId": "listCreditUsage",
        "x-speakeasy-group": "credits",
        "x-speakeasy-name-override": "usage",
        "summary": "List managed-compute credit movements",
        "description": "Requires account-management permission; execution keys receive 403. Returns\nconfirmed, nonzero charges from the configured test or live billing book, the later\ncorrections to them, reservations still held, and reservations released with no\ncharge, newest first. Results are limited to the calling workspace. BYOK work,\nsupplier costs, provider account identities, API-key digests and raw usage evidence\nare not returned; a row's `key_id` names the workspace API key it belongs to. A\ncursor belongs to this workspace and billing mode; invalid or foreign cursors\nreturn 400. New rows do not shift subsequent pages. No provider or payment-provider\ncalls are made.\n",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 20
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 512
            }
          }
        ],
        "responses": {
          "200": {
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "description": "Settled charge page; the amount is the credit debited, not provider cost.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ManagedCreditUsageList"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/usage": {
      "get": {
        "tags": [
          "credits"
        ],
        "operationId": "listUsageReport",
        "x-speakeasy-group": "usage",
        "x-speakeasy-name-override": "list",
        "summary": "List grouped managed and BYOK sandbox usage",
        "description": "Requires account-management permission; execution-only keys receive 403. Reads\nonly this workspace and the configured test or live billing book. Settled managed\ncharges come from verified ledger receipts and are recognized on their settlement\ndate. BYOK costs come from the provider's own cost or usage records priced at\nstored list rates. byok_provider_cost_usd is that exact amount or null, never a\nlocal-clock cost or partial subtotal. No BYOK fee is included because its price-book policy remains\nproposed and unapproved. Current managed reservations are reported as held amounts;\nwith group_by=day they appear under period and group_key `current`, outside the\nrequested historical date range. Dates are inclusive UTC calendar dates and the\nrange may not exceed 92 days. Unknown observations remain null and are counted in\nthe corresponding unknown-sandbox field; a BYOK cost is null when any contributing\nsandbox's provider cost is unknown. The optional provider filter is applied\nbefore grouping to managed and BYOK history and to current managed holds. Cursors\nare scoped to workspace, billing mode and all report filters; malformed or foreign\ncursors return 400. No provider or\npayment-provider calls are made.\n",
        "parameters": [
          {
            "name": "from",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date",
              "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date",
              "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
            }
          },
          {
            "name": "group_by",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "provider",
                "day",
                "key",
                "sandbox"
              ],
              "default": "provider"
            }
          },
          {
            "name": "provider",
            "in": "query",
            "required": false,
            "description": "Restrict rows to this provider before grouping; values use canonical provider identifiers.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 64,
              "pattern": "^[a-z][a-z0-9-]{0,63}$"
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 512
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 1000,
              "default": 100
            }
          }
        ],
        "responses": {
          "200": {
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "description": "One page of grouped usage with an observation timestamp and optional cursor.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UsageReportPage"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/usage.csv": {
      "get": {
        "tags": [
          "credits"
        ],
        "operationId": "exportUsageReportCsv",
        "x-speakeasy-group": "usage",
        "x-speakeasy-name-override": "export_csv",
        "summary": "Export grouped managed and BYOK sandbox usage as CSV",
        "description": "Uses the same workspace, billing mode, date range, filters and page as the JSON usage report. CSV values preserve the JSON report's exact decimal strings; `X-Usage-As-Of` identifies the observation time and `X-Next-Cursor` is present when another page exists.",
        "parameters": [
          {
            "name": "from",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date",
              "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date",
              "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
            }
          },
          {
            "name": "group_by",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "provider",
                "day",
                "key",
                "sandbox"
              ],
              "default": "provider"
            }
          },
          {
            "name": "provider",
            "in": "query",
            "required": false,
            "description": "Restrict rows to this provider before grouping; values use canonical provider identifiers.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 64,
              "pattern": "^[a-z][a-z0-9-]{0,63}$"
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 512
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 1000,
              "default": 100
            }
          }
        ],
        "responses": {
          "200": {
            "headers": {
              "X-Usage-As-Of": {
                "required": true,
                "description": "UTC timestamp for the consistent database snapshot used for this page.",
                "schema": {
                  "type": "string",
                  "format": "date-time"
                }
              },
              "X-Next-Cursor": {
                "required": false,
                "description": "Workspace-scoped cursor for the next page; omitted at the end.",
                "schema": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 512
                }
              },
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "description": "CSV export for the selected page. Header names are `period`, `group_key`,\n`sandbox_count`, `compute_seconds_low`, `compute_seconds_high`,\n`compute_seconds_unknown_sandboxes`, `charge_usd`, `held_usd`,\n`byok_provider_cost_usd`, and `byok_provider_cost_unknown_sandboxes`. Null\nvalues are empty CSV fields, distinct from numeric zero. For example, a row\nwith an unknown group, compute interval, and BYOK provider cost could be:\n\n```csv\nperiod,group_key,sandbox_count,compute_seconds_low,compute_seconds_high,compute_seconds_unknown_sandboxes,charge_usd,held_usd,byok_provider_cost_usd,byok_provider_cost_unknown_sandboxes\n2026-10-01/2026-10-02,,2,,,2,0.000000000,0.000000000,,2\n```\n",
            "content": {
              "text/csv": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/credits/purchases/{purchase_id}": {
      "parameters": [
        {
          "name": "purchase_id",
          "in": "path",
          "required": true,
          "description": "Purchase ID owned by the calling workspace.",
          "schema": {
            "type": "string",
            "minLength": 1
          }
        }
      ],
      "get": {
        "tags": [
          "credits"
        ],
        "operationId": "getCreditPurchase",
        "x-speakeasy-group": "credits",
        "x-speakeasy-name-override": "get_purchase",
        "summary": "Get one credit purchase",
        "description": "The authoritative state to poll after the payer returns from Checkout. Another workspace's purchase is a 404.",
        "responses": {
          "200": {
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "description": "Purchase state.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreditPurchase"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/credits/purchases/{purchase_id}/cancel": {
      "parameters": [
        {
          "name": "purchase_id",
          "in": "path",
          "required": true,
          "description": "Purchase ID owned by the calling workspace.",
          "schema": {
            "type": "string",
            "minLength": 1
          }
        }
      ],
      "post": {
        "tags": [
          "credits"
        ],
        "operationId": "cancelCreditPurchase",
        "x-speakeasy-group": "credits",
        "x-speakeasy-name-override": "cancel_purchase",
        "summary": "Close an unpaid Checkout session",
        "description": "Expires a known open Checkout session for this workspace-owned purchase. A\ncompleted payment is reconciled and remains confirmed. If Checkout creation\nhad an unknown outcome and no session ID was recorded, the same stable Stripe\nidempotency key recovers that request before BoxRouter expires the session.\nRepeating this request is safe. The request needs no body: the return URLs are\noptional and unused when closing a purchase.\n",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CancelCreditPurchase"
              },
              "example": {
                "cancel_url": "https://boxrouter.ai/credits"
              }
            }
          }
        },
        "responses": {
          "200": {
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "description": "Current purchase state after attempting to close Checkout.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreditPurchase"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/credits/promotions": {
      "post": {
        "tags": [
          "credits"
        ],
        "operationId": "redeemCreditPromotion",
        "x-speakeasy-group": "credits",
        "x-speakeasy-name-override": "redeem",
        "summary": "Redeem a promotion code for free credit",
        "description": "Adds the code's credit to the workspace balance, once per workspace. Codes are\ncase-insensitive and surrounding spaces are ignored. An unknown, expired, disabled\nor fully used code is 404 promotion_code_invalid; these cases are not told apart.\nA new redemption answers 201. A code this workspace already redeemed is refused\nwith 409 promotion_already_redeemed and details.redemption containing the original redemption;\nits message names the redemption date. No credit is granted again. Promotional\ncredit does not expire. Requires account-management permission; 503 payments_unavailable while\ncredits are not configured.\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RedeemCreditPromotion"
              },
              "example": {
                "code": "WELCOME-EXAMPLE"
              }
            }
          }
        },
        "responses": {
          "201": {
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "description": "The new redemption; read the balance again to see the new total.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreditPromotion"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "get": {
        "tags": [
          "credits"
        ],
        "operationId": "listCreditPromotions",
        "x-speakeasy-group": "credits",
        "x-speakeasy-name-override": "promotions",
        "summary": "List redeemed promotion codes",
        "description": "Promotion codes this workspace redeemed, newest first.",
        "responses": {
          "200": {
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "description": "Redemptions, newest first.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreditPromotionList"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/credits/billing-details": {
      "get": {
        "tags": [
          "credits"
        ],
        "operationId": "getCreditBillingDetails",
        "x-speakeasy-group": "credits",
        "x-speakeasy-name-override": "billing_details",
        "summary": "Get workspace billing details",
        "description": "Requires account-management permission. Reads the workspace Stripe customer. When multiple customer tax IDs exist, tax_id is the newest by creation time (ID breaks ties). Unset details are null.",
        "responses": {
          "200": {
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "description": "Current workspace billing details.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BillingDetails"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "put": {
        "tags": [
          "credits"
        ],
        "operationId": "updateCreditBillingDetails",
        "x-speakeasy-group": "credits",
        "x-speakeasy-name-override": "update_billing_details",
        "summary": "Replace workspace billing details",
        "description": "Stores legal name, invoice email, address and one tax ID on the workspace Stripe customer, creating it when absent. Details apply to future invoices. PUT replaces all customer tax IDs with the supplied single ID, adding the replacement before deleting old IDs so a rejected replacement preserves them. Stripe tax ID verification can be pending or unsuccessful. Repeat an uncertain update with the same Idempotency-Key; a changed body under that key returns 409. Stripe rejection returns 502; the update can have partially completed, so read current details before correcting it.",
        "parameters": [
          {
            "$ref": "#/components/parameters/RequiredIdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateBillingDetails"
              },
              "example": {
                "name": "Example Labs, Inc.",
                "email": "billing@example.com",
                "address": {
                  "line1": "1 Example Street",
                  "line2": null,
                  "city": "Springfield",
                  "state": "IL",
                  "postal_code": "62701",
                  "country": "US"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "description": "Workspace billing details after the update.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BillingDetails"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/credits/alerts": {
      "get": {
        "tags": [
          "credits"
        ],
        "operationId": "getCreditAlerts",
        "x-speakeasy-group": "credits",
        "x-speakeasy-name-override": "alerts",
        "summary": "Get workspace credit alert settings",
        "description": "Requires account-management permission. Returns workspace-owned settings only.",
        "responses": {
          "200": {
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "description": "Current workspace credit alert settings.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreditAlerts"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "put": {
        "tags": [
          "credits"
        ],
        "operationId": "updateCreditAlerts",
        "x-speakeasy-group": "credits",
        "x-speakeasy-name-override": "update_alerts",
        "summary": "Replace workspace credit alert settings",
        "description": "Atomically replaces the optional trigger level and evaluates the current available balance. Repeating identical settings is idempotent and requires no Idempotency-Key. Sends the owner one alert per crossing below the trigger level and one when available credit is zero or negative; a repeated evaluation does not resend. Re-arms at or above the trigger level and above zero respectively. BYOK work is unaffected by credit balance.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreditAlertsUpdate"
              },
              "example": {
                "low_balance_threshold_minor": 1000
              }
            }
          }
        },
        "responses": {
          "200": {
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "description": "Workspace credit alert settings after the update.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreditAlerts"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/credits/payment-methods": {
      "get": {
        "tags": [
          "credits"
        ],
        "operationId": "listCreditPaymentMethods",
        "x-speakeasy-group": "credits",
        "x-speakeasy-name-override": "payment_methods",
        "summary": "List saved workspace payment methods",
        "description": "Returns masked card details only. Saved methods can be charged for a workspace member's purchase or immediately when enabling auto top-up with a trigger level above the current balance.",
        "responses": {
          "200": {
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "description": "Saved cards in the Stripe customer profile.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreditPaymentMethodList"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/credits/payment-methods/setup": {
      "post": {
        "tags": [
          "credits"
        ],
        "operationId": "createCreditPaymentMethodSetup",
        "x-speakeasy-group": "credits",
        "x-speakeasy-name-override": "setup_payment_method",
        "summary": "Start hosted setup for a saved payment method",
        "description": "Creates a Stripe-hosted setup page and returns its URL. Setup does not charge the\npayer. The completed method can be charged for a later user-initiated purchase or immediately when enabling auto top-up with a trigger level above the current balance.\nRepeating the request with the same Idempotency-Key returns the same page.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/RequiredIdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreatePaymentMethodSetup"
              },
              "example": {
                "success_url": "https://boxrouter.ai/credits",
                "cancel_url": "https://boxrouter.ai/credits"
              }
            }
          }
        },
        "responses": {
          "201": {
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "description": "Payment method setup session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StartedPaymentMethodSetup"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/credits/payment-methods/setup-intent": {
      "post": {
        "tags": [
          "credits"
        ],
        "operationId": "createCreditPaymentMethodSetupIntent",
        "x-speakeasy-group": "credits",
        "x-speakeasy-name-override": "setup_payment_method_intent",
        "summary": "Start in-page saved card setup",
        "description": "Creates a Stripe SetupIntent for in-page card collection. Requires account-management permission and the in-page cards feature.",
        "responses": {
          "201": {
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "description": "Stripe client configuration for card setup.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreditSetupIntent"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "description": "Five card setup attempts were recorded for the organization in the last hour (card_setup_rate_limit).",
            "headers": {
              "Retry-After": {
                "description": "Seconds until the organization may start another card setup.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            }
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/credits/payment-methods/order": {
      "put": {
        "tags": [
          "credits"
        ],
        "operationId": "reorderCreditPaymentMethods",
        "x-speakeasy-group": "credits",
        "x-speakeasy-name-override": "reorder_payment_methods",
        "summary": "Set saved card charge order",
        "description": "Replaces the order of every saved card and Link method for automatic top-up. Requires account-management permission and the multi-card top-up feature.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReorderCreditPaymentMethods"
              },
              "example": {
                "payment_method_ids": [
                  "pm_1Example",
                  "pm_2Example"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "description": "Saved payment methods in charge order.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreditPaymentMethodList"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/credits/payment-method-setups/{setup_id}": {
      "parameters": [
        {
          "name": "setup_id",
          "in": "path",
          "required": true,
          "description": "Setup ID owned by the calling workspace.",
          "schema": {
            "type": "string",
            "minLength": 1
          }
        }
      ],
      "get": {
        "tags": [
          "credits"
        ],
        "operationId": "getCreditPaymentMethodSetup",
        "x-speakeasy-group": "credits",
        "x-speakeasy-name-override": "get_payment_method_setup",
        "summary": "Get a saved payment method setup status",
        "description": "Reads Stripe's current setup state after the payer returns. Another workspace's setup is a 404.",
        "responses": {
          "200": {
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "description": "Setup state.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentMethodSetup"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/credits/payment-methods/{payment_method_id}": {
      "parameters": [
        {
          "name": "payment_method_id",
          "in": "path",
          "required": true,
          "description": "Stripe payment method ID owned by the calling workspace.",
          "schema": {
            "type": "string",
            "pattern": "^pm_[A-Za-z0-9_]+$"
          }
        }
      ],
      "delete": {
        "tags": [
          "credits"
        ],
        "operationId": "deleteCreditPaymentMethod",
        "x-speakeasy-group": "credits",
        "x-speakeasy-name-override": "delete_payment_method",
        "summary": "Remove a saved workspace payment method",
        "description": "Detaches a saved card. Another workspace's payment method is a 404. If the card\nwas the default, the next saved card becomes default; removing the last card\ndisables auto top-up with disabled_reason payment_method_required.\n",
        "responses": {
          "204": {
            "description": "Payment method removed.",
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/credits/payment-methods/{payment_method_id}/default": {
      "parameters": [
        {
          "name": "payment_method_id",
          "in": "path",
          "required": true,
          "description": "Stripe payment method ID owned by the calling workspace.",
          "schema": {
            "type": "string",
            "pattern": "^pm_[A-Za-z0-9_]+$"
          }
        }
      ],
      "post": {
        "tags": [
          "credits"
        ],
        "operationId": "setCreditDefaultPaymentMethod",
        "x-speakeasy-group": "credits",
        "x-speakeasy-name-override": "set_default_payment_method",
        "summary": "Set the workspace's default saved card",
        "description": "Makes this workspace-owned saved card the only default card. The first saved\ncard becomes default automatically. This local setting is used by one-click\npurchases and auto top-up; repeating the request is safe. Another workspace's\ncard is a 404.\n",
        "responses": {
          "200": {
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "description": "The saved card, now the workspace default.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreditPaymentMethod"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/credits/auto-top-up": {
      "get": {
        "tags": [
          "credits"
        ],
        "operationId": "getCreditAutoTopUp",
        "x-speakeasy-group": "credits",
        "x-speakeasy-name-override": "auto_top_up",
        "summary": "Get automatic credit top-up settings",
        "description": "Requires account-management permission. Auto top-up is off until explicitly enabled.",
        "responses": {
          "200": {
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "description": "Workspace auto top-up settings and most recent attempt.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreditAutoTopUp"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "put": {
        "tags": [
          "credits"
        ],
        "operationId": "updateCreditAutoTopUp",
        "x-speakeasy-group": "credits",
        "x-speakeasy-name-override": "update_auto_top_up",
        "summary": "Replace automatic credit top-up settings",
        "description": "Stores the enabled state, trigger level and purchase amount. The amount must be\nwithin current purchase_bounds_minor and the trigger level must be zero or greater.\nEnabling requires a default saved card. Enabling with a trigger level above current\navailable credit evaluates and attempts one top-up immediately. An attempt is\nmade once per crossing below the trigger level and is never retried automatically. A\ndecline or required authentication disables auto top-up and records the reason.\nRepeating the same settings is idempotent and does not start a second attempt for\nthe same balance crossing. After a 503 with outcome unknown, retry the identical\nsettings or GET the settings; inspect last_attempt.purchase_id and poll that\npurchase to reconcile the original attempt.\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateCreditAutoTopUp"
              },
              "example": {
                "enabled": true,
                "threshold_minor": 500,
                "amount_minor": 2500
              }
            }
          }
        },
        "responses": {
          "200": {
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "description": "Workspace auto top-up settings after evaluation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreditAutoTopUp"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/sandboxes/{sandbox_id}/terminals": {
      "parameters": [
        {
          "$ref": "#/components/parameters/SandboxId"
        }
      ],
      "post": {
        "tags": [
          "terminals"
        ],
        "operationId": "openTerminal",
        "x-speakeasy-group": "terminals",
        "x-speakeasy-name-override": "open",
        "summary": "Open a terminal",
        "description": "Opens a real PTY running a Bash login shell on any active provider. A small\nPython 3 helper in the guest owns the PTY, so the sandbox image must provide\n`python3`. Opens once and returns a BoxRouter terminal handle; the shell ends at\n`timeout_seconds`, on `kill`, when it exits, or with the sandbox. Terminal\nconnections and output expire on API worker loss; the durable open record still\nprevents another dispatch. No automatic recovery or replay.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OpenSandboxTerminal"
              },
              "example": {
                "columns": 120,
                "rows": 30
              }
            }
          }
        },
        "responses": {
          "201": {
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "description": "Terminal handle created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SandboxTerminal"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/sandboxes/{sandbox_id}/terminals/{terminal_id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/SandboxId"
        },
        {
          "$ref": "#/components/parameters/TerminalId"
        }
      ],
      "get": {
        "tags": [
          "terminals"
        ],
        "operationId": "getTerminal",
        "x-speakeasy-group": "terminals",
        "x-speakeasy-name-override": "get",
        "summary": "Get observed terminal state",
        "description": "Reads an owned terminal record without consuming output.",
        "responses": {
          "200": {
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "description": "Terminal state; an unknown exit code remains null.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SandboxTerminal"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "410": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/sandboxes/{sandbox_id}/terminals/{terminal_id}/events": {
      "parameters": [
        {
          "$ref": "#/components/parameters/SandboxId"
        },
        {
          "$ref": "#/components/parameters/TerminalId"
        }
      ],
      "get": {
        "tags": [
          "terminals"
        ],
        "operationId": "streamTerminalEvents",
        "x-boxrouter-stream-terminal-types": [
          "exit",
          "error"
        ],
        "x-speakeasy-group": "terminals",
        "x-speakeasy-name-override": "events",
        "summary": "Stream terminal output and its end",
        "description": "You can rely on:\n- Input order is kept and output applies backpressure on PTY routes.\n- Closing an observer does not by itself end the process.\n\nYou can set: input, dimensions. Observation controls where supported.\n\nNot promised: unlimited concurrent observers.\n\nServer-sent events. Each data field contains one JSON TerminalEvent; the SSE id\nis its sequence. Output events carry exact bytes as base64. An exit event follows\nall output. An error event may arrive after HTTP 200 and ends the stream without\nimplying the shell stopped. EOF without an exit or error event is an incomplete\nstream, not success.\n\nOutput is retained in a 1 MiB sliding window until 60 seconds after the shell\nends. Last-Event-ID resumes after that event while it is retained; a dropped\nsequence returns 410, or an error event for a reader that falls behind, and is\nnever skipped silently. Without Last-Event-ID the stream starts at the oldest\nretained event.\n",
        "parameters": [
          {
            "name": "Last-Event-ID",
            "in": "header",
            "description": "Last fully consumed event sequence from this terminal stream.",
            "schema": {
              "type": "string",
              "pattern": "^[0-9]+$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Typed SSE stream with exactly one exit or error event on normal completion.",
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              },
              "X-Event-Retention-Seconds": {
                "description": "Minimum retention after the shell ends for this stream's events.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "text/event-stream": {
                "schema": {
                  "$ref": "#/components/schemas/SandboxTerminalEventSSE"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "410": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/sandboxes/{sandbox_id}/terminals/{terminal_id}/input": {
      "parameters": [
        {
          "$ref": "#/components/parameters/SandboxId"
        },
        {
          "$ref": "#/components/parameters/TerminalId"
        }
      ],
      "post": {
        "tags": [
          "terminals"
        ],
        "operationId": "writeTerminalInput",
        "x-speakeasy-group": "terminals",
        "x-speakeasy-name-override": "write",
        "summary": "Write terminal input",
        "description": "You can rely on:\n- Input order is kept and output applies backpressure on PTY routes.\n- Closing an observer does not by itself end the process.\n\nYou can set: input, dimensions. Observation controls where supported.\n\nNot promised: unlimited concurrent observers.\n\nWrites exact bytes to the PTY once. Await calls sequentially to preserve order.\nEach call is one command round trip on the provider. An uncertain write must not\nbe replayed with a new key. Returns 409 after the shell has ended.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SandboxTerminalInput"
              },
              "example": {
                "data_base64": "bHMgLWxhCg=="
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "Input delivered to the PTY; application consumption is not guaranteed.",
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "410": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/sandboxes/{sandbox_id}/terminals/{terminal_id}/resize": {
      "parameters": [
        {
          "$ref": "#/components/parameters/SandboxId"
        },
        {
          "$ref": "#/components/parameters/TerminalId"
        }
      ],
      "post": {
        "tags": [
          "terminals"
        ],
        "operationId": "resizeTerminal",
        "x-speakeasy-group": "terminals",
        "x-speakeasy-name-override": "resize",
        "summary": "Resize the terminal window",
        "description": "You can rely on:\n- Changes the terminal's window size, or is refused where the sandbox cannot resize an open terminal.\n\nYou can set: columns, rows.\n\nNot promised: when the running program notices the new size.\n\nThe foreground program receives SIGWINCH. Where the sandbox cannot resize an open\nterminal, the refusal is `409 capability_unavailable`; open the terminal at the size\nyou need.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SandboxTerminalSize"
              },
              "example": {
                "columns": 120,
                "rows": 30
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "Window size applied.",
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "410": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/sandboxes/{sandbox_id}/terminals/{terminal_id}/kill": {
      "parameters": [
        {
          "$ref": "#/components/parameters/SandboxId"
        },
        {
          "$ref": "#/components/parameters/TerminalId"
        }
      ],
      "post": {
        "tags": [
          "terminals"
        ],
        "operationId": "killTerminal",
        "x-speakeasy-group": "terminals",
        "x-speakeasy-name-override": "kill",
        "summary": "Hang up the terminal without destroying its sandbox",
        "description": "You can rely on:\n- Ends the terminal's shell without destroying the sandbox, or is refused where the sandbox cannot end it from outside; ending a terminal that already ended succeeds until the terminal expires.\n\nNot promised: that the shell has already ended when the call returns (its exit event shows when it does); that the whole process group receives the hang-up.\n\nIt sends a hang-up to the shell's process group where the provider allows that, and\notherwise ends the shell process. The terminal's exit event carries the shell's exit\ncode, or -1 when, after a kill, the provider ends the terminal without reporting one. Closing an\nevents connection never calls this. Where the sandbox cannot end a terminal's shell from\noutside, the refusal is `409 capability_unavailable`; type `exit` in the terminal or\ndestroy the sandbox. A terminal expires 60 seconds after its shell ends: until then a\nkill answers 204, afterwards `410 expired`.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "204": {
            "description": "Hang-up delivered, or the shell had already ended.",
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "410": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/secrets": {
      "get": {
        "tags": [
          "secrets"
        ],
        "operationId": "listSecrets",
        "x-speakeasy-group": "secrets",
        "x-speakeasy-name-override": "list",
        "summary": "List workspace secret names",
        "description": "Requires `credentials:manage` on API keys; dashboard browser sessions are also\nauthorized. An execution key alone cannot administer workspace secrets. Lists\nmetadata only; secret values are never returned.\n",
        "responses": {
          "200": {
            "description": "Workspace secret names and timestamps.",
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SecretList"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/secrets/{name}": {
      "parameters": [
        {
          "name": "name",
          "in": "path",
          "required": true,
          "description": "Workspace secret name.",
          "schema": {
            "$ref": "#/components/schemas/SecretName"
          }
        }
      ],
      "put": {
        "tags": [
          "secrets"
        ],
        "operationId": "putSecret",
        "x-speakeasy-group": "secrets",
        "x-speakeasy-name-override": "put",
        "summary": "Store a workspace secret",
        "description": "Requires `credentials:manage` on API keys; dashboard browser sessions are also\nauthorized. An execution key alone cannot administer workspace secrets. Create or\nreplace a workspace-scoped secret. The value is accepted only in this request body;\nit is never returned by this or any secret listing operation.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PutSecret"
              },
              "example": {
                "value": "example-secret-value"
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "Secret stored without returning its value.",
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            }
          },
          "400": {
            "description": "Secret name or value is invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvalidRequestErrorResponse"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "delete": {
        "tags": [
          "secrets"
        ],
        "operationId": "deleteSecret",
        "x-speakeasy-group": "secrets",
        "x-speakeasy-name-override": "delete",
        "summary": "Delete a workspace secret",
        "description": "Requires `credentials:manage` on API keys; dashboard browser sessions are also\nauthorized. An execution key alone cannot administer workspace secrets. Remove the\nnamed workspace secret and return no secret data.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "204": {
            "description": "Secret removed.",
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/sandboxes/{sandbox_id}/previews": {
      "parameters": [
        {
          "$ref": "#/components/parameters/SandboxId"
        }
      ],
      "get": {
        "tags": [
          "previews"
        ],
        "operationId": "listPreviews",
        "summary": "List a sandbox's open previews",
        "description": "You can rely on:\n- Lists the previews this sandbox has open, as recorded when they were opened; a resume forgets them, so the list is empty until one is opened again.\n\nYou can set: cursor, limit.\n\nNot promised: that a listed preview still works.\n\nRecords only: this call observes no provider.\n",
        "x-speakeasy-group": "previews",
        "x-speakeasy-name-override": "list",
        "parameters": [
          {
            "$ref": "#/components/parameters/Cursor"
          },
          {
            "$ref": "#/components/parameters/Limit"
          }
        ],
        "responses": {
          "200": {
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "description": "The recorded previews of this sandbox.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PreviewPage"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "post": {
        "tags": [
          "previews"
        ],
        "operationId": "openPreview",
        "summary": "Get a URL for a sandbox port",
        "description": "You can rely on:\n- A private preview never falls back to a public link, and a requested credential form never falls back to the other; a mode the sandbox cannot enforce is refused. A route whose declaration cannot enforce the mode is refused before anything is opened; a weaker preview a route does open is ended before the refusal, or the refusal says it may still be reachable and names its port and id.\n- Opening a port that already has a preview with the same access returns that preview instead of opening a second one.\n\nYou can set: port, access, credential.\n\nNot promised: that an application is listening on the port; an expiry time unless one is enforced.\n\nReturns an HTTPS URL for one port in the sandbox and, when the link is private, where its\ncredential is carried. The sandbox must have been created with the `previews`\nrequirement naming that port and the access you ask for.\n\n404 means the sandbox does not exist in this workspace. A sandbox that exists but\nwas not created through this API is refused with `409 invalid_state`; one that has\nended answers `410 sandbox_ended`.\n\nA preview is never returned with other access than the request asked for. When the\nprovider answers with one (for example a public link for a private request), the call\nis refused with `502 preview_access_refused` and the unwanted preview is ended where\nthe provider allows. `details.port` names the port. `details.revoked` is true when it\nwas ended and no access remains. When it could not be ended the outcome is `unknown`,\nthe message says the preview may still be reachable, and `details.preview_id` and\n`details.url` name a public one (a private preview's address holds a credential and is\nnever repeated). The operation stays open for reconciliation: do not send the call\nagain; end the sandbox to be certain no access remains.\n",
        "x-sandbox-provider-spec-next-errors": [
          "not_named",
          "not_running",
          "gate_unavailable"
        ],
        "x-speakeasy-group": "previews",
        "x-speakeasy-name-override": "open",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OpenPreview"
              },
              "example": {
                "port": 3000,
                "access": "public"
              }
            }
          }
        },
        "responses": {
          "200": {
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "description": "This port already had a preview with this access, so it is returned unchanged.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Preview"
                }
              }
            }
          },
          "201": {
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "description": "Preview URL and, for a private link, where its credential is.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Preview"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "410": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-boxrouter-capability": {
          "kind": "gate",
          "gate": "previews"
        }
      }
    },
    "/sandboxes/{sandbox_id}/previews/{preview_id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/SandboxId"
        },
        {
          "$ref": "#/components/parameters/PreviewId"
        }
      ],
      "delete": {
        "tags": [
          "previews"
        ],
        "operationId": "revokePreview",
        "summary": "Revoke a preview",
        "description": "You can rely on:\n- Access through the named preview ends while the sandbox and its other previews keep running; revoking a preview that already ended succeeds.\n\nYou can set: preview id.\n\nEnds a preview, named by the ID that opening it returned. The sandbox must have been created\nwith `previews.revocable` set to `true`; otherwise the call fails with `not_named`, and `fix`\nshows the requirement to send. A sandbox that is not running fails with `not_running`, even\nif the preview has already ended. Otherwise, ending a preview that has already ended answers\n`204`.\n",
        "x-speakeasy-group": "previews",
        "x-speakeasy-name-override": "revoke",
        "x-sandbox-provider-spec-next-errors": [
          "not_named",
          "not_running",
          "gate_unavailable"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "204": {
            "description": "Access ended, or already ended.",
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-boxrouter-capability": {
          "kind": "gate",
          "gate": "previews"
        }
      }
    },
    "/sandboxes/{sandbox_id}/browser": {
      "parameters": [
        {
          "$ref": "#/components/parameters/SandboxId"
        }
      ],
      "post": {
        "tags": [
          "sandboxes"
        ],
        "operationId": "ensureBrowser",
        "x-speakeasy-group": "sandboxes",
        "x-speakeasy-name-override": "browser",
        "summary": "Prove a headless Chromium in the sandbox",
        "description": "You can rely on:\n- Returns only the automation channels that loaded a page served inside the sandbox; when none does, the call is refused.\n\nNot promised: installing a browser in the sandbox.\n\nLoads a page from a server inside the guest in the image's own headless Chromium\nand reads the CDP endpoint: Playwright and CDP on glibc images, CDP on Alpine.\nCreate the sandbox from an image with Python 3 and Playwright with Chromium (or a\nChromium binary); BoxRouter's standard image has neither. An image without them, or a sandbox\nwhere no channel passes, such as one with too little memory, is refused with\n`422 unsupported_feature`. Afterwards run browser scripts through commands or processes.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "200": {
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "description": "The browser and the automation channels it proved.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Browser"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/sandboxes/{sandbox_id}/pause": {
      "parameters": [
        {
          "$ref": "#/components/parameters/SandboxId"
        }
      ],
      "post": {
        "tags": [
          "sandboxes"
        ],
        "operationId": "pauseSandbox",
        "x-speakeasy-group": "sandboxes",
        "x-speakeasy-name-override": "pause",
        "summary": "Pause a sandbox and keep it",
        "description": "You can rely on:\n- On return the sandbox is paused, and the result says whether running processes are kept or only files.\n- The remaining lifetime budget is preserved.\n\nYou can set: lifetime.\n\nStops compute and keeps the sandbox where it is. The sandbox must have been created with\nthe `pause_resume` requirement. The result says what was kept (running processes, or\nonly files) and how much lifetime remains. Resume the sandbox before doing more work in it.\n\n404 means the sandbox does not exist in this workspace. A sandbox that exists but\nwas not created through this API is refused with `409 invalid_state`; one that has\nended answers `410 sandbox_ended`.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "200": {
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "description": "The pause result.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Paused"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "410": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-boxrouter-capability": {
          "kind": "gate",
          "gate": "pause_resume"
        }
      }
    },
    "/sandboxes/{sandbox_id}/resume": {
      "parameters": [
        {
          "$ref": "#/components/parameters/SandboxId"
        }
      ],
      "post": {
        "tags": [
          "sandboxes"
        ],
        "operationId": "resumeSandbox",
        "x-speakeasy-group": "sandboxes",
        "x-speakeasy-name-override": "resume",
        "summary": "Resume the same paused sandbox",
        "description": "You can rely on:\n- Resumes the same sandbox on its original provider and account, never a replacement.\n- On return the sandbox is running, and the result says whether processes from before the pause were lost.\n- The sandbox runs on with the lifetime budget it had left; resume takes no new budget.\n- Resuming a sandbox that is already running succeeds and changes nothing, so a retry is safe.\n\nNot promised: that previews opened before the pause still work.\n\nStarts a paused or stopped sandbox again and returns its remaining lifetime. Resume takes\nno fields: send no body or `{}`, and any other field fails with `400 invalid_request`. To\nchange how long the sandbox may run, extend its lifetime, which works while it is running,\npaused or stopped.\n\nResuming a sandbox that is already running changes nothing, so you can safely send the call\nagain. 404 means the sandbox does not exist in this workspace. A sandbox that cannot be\nresumed fails with 409: `invalid_state` while it is being created or destroyed, or when it\nwas not created through this API; `lifetime_used_up` when its lifetime is spent (extend it,\nthen resume); `volume_lease_lost` or `volume_busy` when its Volume cannot follow. A sandbox\nthat has ended answers `410 sandbox_ended`.\n\nThose refusals happen before anything is resumed and report `outcome: not_started`. If the\nprovider resumed the sandbox and a later step failed, the outcome is never `not_started`:\n`502 volume_restore_failed` (the sandbox restarted without its Volume mounted) reports\n`outcome: partial` with an `operation_id`, and the sandbox is running without its Volume.\nDo not send the resume again; destroy the sandbox and create a new one with the Volume\nattached. A lifetime failure after the resume reports `outcome: unknown`; read the operation\nbefore acting.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Resume"
              },
              "example": {}
            }
          }
        },
        "responses": {
          "200": {
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "description": "The resumed sandbox's state and lifetime.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Resumed"
                }
              }
            }
          },
          "204": {
            "description": "The sandbox was already running; nothing changed.",
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "410": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-boxrouter-capability": {
          "kind": "recovery"
        }
      }
    },
    "/sandboxes/{sandbox_id}/lifetime": {
      "parameters": [
        {
          "$ref": "#/components/parameters/SandboxId"
        }
      ],
      "post": {
        "tags": [
          "sandboxes"
        ],
        "operationId": "extendSandboxLifetime",
        "summary": "Extend a sandbox lifetime",
        "description": "You can rely on:\n- The value is the new total running-time budget, not an increment, so sending it again is safe; a budget shorter than the current one or than the running time already used is refused. On success the sandbox may run for at least the requested total; extending a paused or stopped sandbox sets the budget it resumes with.\n\nYou can set: lifetime_seconds.\n\nNot promised: that the sandbox ends exactly when the budget runs out.\n\nRefused with not_named unless the creation request asked for resources.extendable_lifetime. It is\nnot a re-match: the only check is the route's max_lifetime_seconds for this account,\nagainst the current run, and over it the answer is lifetime_limit. Allowed while\nrunning, paused or stopped: a paused or stopped sandbox resumes with the new budget.\nA total shorter than the current budget is invalid_request (400); a total below the\nrunning time already used is lifetime_limit (409).\n\n404 means the sandbox does not exist in this workspace. A sandbox that exists but\nwas not created through this API is refused with `409 invalid_state`; one that has\nended answers `410 sandbox_ended`.\n",
        "x-speakeasy-group": "sandboxes",
        "x-speakeasy-name-override": "extend",
        "x-sandbox-provider-spec-next-errors": [
          "not_named",
          "lifetime_limit"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "lifetime_seconds"
                ],
                "properties": {
                  "lifetime_seconds": {
                    "type": "integer",
                    "minimum": 1,
                    "description": "The new total running-time budget, not an increment."
                  }
                }
              },
              "example": {
                "lifetime_seconds": 1800
              }
            }
          }
        },
        "responses": {
          "200": {
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "description": "The lifetime as it now stands.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Lifetime"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "410": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-boxrouter-capability": {
          "kind": "resource",
          "resource": "extendable_lifetime"
        }
      }
    },
    "/sandboxes/{sandbox_id}/network-policy": {
      "parameters": [
        {
          "$ref": "#/components/parameters/SandboxId"
        }
      ],
      "post": {
        "tags": [
          "sandboxes"
        ],
        "operationId": "updateNetworkPolicy",
        "summary": "Change a running sandbox's outbound network policy",
        "description": "You can rely on:\n- Connections opened after the call returns follow the new policy, and the sandbox keeps its processes and files.\n- An uncertain outcome is never resent.\n\nYou can set: policy, allow, deny.\n\nNot promised: that connections already open when the call returns are closed; name lookups and DNS traffic.\n\nSwitches the sandbox's outbound network policy, or changes its entries. Each call starts\nfrom the policy the sandbox has now: the last one this call applied, or else the one named\nwhen the sandbox was created (`open` if it named none).\n\nThe sandbox must have been created with the `network_lockdown` requirement naming the\nsettings the change needs. Otherwise the call fails with `not_named`, and `fix` shows the\nrequirement to send:\n\n- Switching to a different policy needs `switchable`, and the target policy listed in\n  `switches_to` unless it is the policy the sandbox was created with. Switching back to the\n  created policy with different entries also needs `changeable`.\n- Changing the entries of the current policy needs `changeable`, even when the entries are\n  the same. After one switch, a further call that names the new policy needs `changeable`.\n- Deny entries on an allowlist need `deny_wins`, and an HTTP rule among the entries needs\n  `http_rules`.\n\n`422 unsupported_feature` with outcome `not_started` means the route cannot switch policies.\n",
        "x-speakeasy-group": "sandboxes",
        "x-speakeasy-name-override": "update_network_policy",
        "x-sandbox-provider-spec-next-errors": [
          "not_named",
          "gate_unavailable",
          "invalid_request",
          "not_found"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateNetworkPolicy"
              },
              "example": {
                "policy": "allowlist",
                "allow": [
                  "pypi.org",
                  "files.pythonhosted.org"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "description": "The policy now enforced.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NetworkPolicyUpdated"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-boxrouter-capability": {
          "kind": "gate",
          "gate": "network_lockdown"
        }
      }
    },
    "/provider-accounts": {
      "post": {
        "tags": [
          "provider-accounts"
        ],
        "operationId": "connectProviderAccount",
        "x-speakeasy-group": "provider_accounts",
        "x-speakeasy-name-override": "connect",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "summary": "Connect a provider account",
        "description": "Saves your own provider credentials so BoxRouter can run sandboxes on that account. Needs\nthe `provider-accounts:manage` permission on the API key; a signed-in dashboard session also\nworks. This permission is separate from the access that creates sandboxes.\n\nBoxRouter first makes one read-only request to the provider with the credentials. A clear\nrejection fails with `422 credentials_rejected`; an unreachable provider or an inconclusive\nanswer does not block the save. The credentials are then stored encrypted and never\nreturned. The account is enabled at once. Connecting starts no sandbox and prepares\nnothing in your provider account: the first sandbox that needs the standard image\nprepares it, or run the standard image setup to prepare it now.\n\nIf the key matches one you already connected (same provider, settings and last four\ncharacters), the account is still connected and the response carries a\n`duplicate_credential` warning naming the other account. Connecting or testing an account\nwhose provider is not enabled for you fails with `409 provider_not_enabled`.\n\nProvider connection settings, such as a custom URL or proxy, and credentials that run your\ncode need extra authority on the key. Submitting a URL or proxy does not by itself give\nBoxRouter network access to that host. For credentials that run your code, send the ID of an\nartifact you uploaded; an unknown or expired artifact fails with `404`. The response\nreturns account metadata only, never the code, configuration or tokens. Sending the same\nrequest again reuses the recorded outcome, and a request still waiting on the provider\nfails with `409` instead of running your code a second time.\n\nIf the provider later answers with `401` or `403`, the account's status becomes\n`credentials_rejected`; the status carries a safe cause and the action that restores access.\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ConnectProviderAccount"
              },
              "example": {
                "name": "my-account",
                "credentials": {
                  "provider": "example-provider",
                  "api_key": "example-api-key-value"
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "description": "Connected-account record, without credentials.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProviderAccount"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "get": {
        "tags": [
          "provider-accounts"
        ],
        "operationId": "listProviderAccounts",
        "x-speakeasy-group": "provider_accounts",
        "x-speakeasy-name-override": "list",
        "summary": "List connected accounts",
        "description": "Requires `provider-accounts:manage` on API keys; dashboard browser sessions are also\nauthorized. Returns your workspace's account metadata and the list of providers enabled for you;\nit never returns stored credentials.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/Cursor"
          },
          {
            "$ref": "#/components/parameters/Limit"
          }
        ],
        "responses": {
          "200": {
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "description": "Connected accounts in this workspace.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProviderAccountPage"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/provider-accounts/test": {
      "post": {
        "tags": [
          "provider-accounts"
        ],
        "operationId": "testProviderCredentials",
        "x-speakeasy-group": "provider_accounts",
        "x-speakeasy-name-override": "test_credentials",
        "summary": "Test provider credentials without saving them",
        "description": "Checks credentials without saving them. Needs the `provider-accounts:manage` permission on\nthe API key; a signed-in dashboard session also works. BoxRouter makes the same read-only\nrequest to the provider as when it tests a saved account, using the credentials in the body.\nNothing is stored and no account is created or changed, so no idempotency key is needed.\n\nCredentials that run your code are not accepted here. Connection settings, such as a custom\nURL, are accepted and choose where the request goes; they need extra authority on the key,\nand submitting a URL or proxy does not by itself give BoxRouter network access to that host.\nThe response returns the provider's own status and body, up to 4096 characters, without\nadding a validation message.\n\nFails with `409 provider_not_enabled` when this provider is not enabled for you.\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TestProviderCredentials"
              },
              "example": {
                "credentials": {
                  "provider": "example-provider",
                  "api_key": "example-api-key-value"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "description": "Raw result of the read-only provider request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProviderAccountTest"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "413": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/provider-accounts/{account_id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/AccountId"
        }
      ],
      "get": {
        "tags": [
          "provider-accounts"
        ],
        "operationId": "getProviderAccount",
        "x-speakeasy-group": "provider_accounts",
        "x-speakeasy-name-override": "get",
        "summary": "Get connected-account metadata",
        "description": "Requires `provider-accounts:manage` on API keys; dashboard browser sessions are also\nauthorized. The account must be visible within the caller's workspace. Never reveals\nkey material.\n",
        "responses": {
          "200": {
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "description": "Account metadata and current credential version.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProviderAccount"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "delete": {
        "tags": [
          "provider-accounts"
        ],
        "operationId": "disconnectProviderAccount",
        "x-speakeasy-group": "provider_accounts",
        "x-speakeasy-name-override": "disconnect",
        "summary": "Remove a connected account",
        "description": "Requires `provider-accounts:manage` on API keys; dashboard browser sessions are also\nauthorized. Reject with 409 while owned\nresources, pending mutations or unresolved cleanup still depend on this\ncredential. Never orphan sandboxes silently or transfer them to managed\nbilling. Removes the stored secret; does not revoke the upstream token.\nFor callable credentials, close all unreferenced factory workers and remove\ntheir retained code/configuration and acquired secrets. Pending acquisitions\nand retained credential-version dependencies also prevent disconnection.\n\nRemoval waits for work already running on the account (standard-image setup,\nActions runner-image checks), which can take minutes. With `wait=false` the\nrequest returns 202 at once with the account and `disconnect.state:\ndisconnecting`, and finishes in the background: read the account until it\nreturns 404 (removed) or `disconnect.state: failed`, whose `error` is the\nrefusal this request would otherwise have returned, with the account still\nconnected. Repeating the request while a removal runs returns the same 202 and\nstarts nothing new.\n",
        "parameters": [
          {
            "name": "wait",
            "in": "query",
            "required": false,
            "description": "true (default) answers when the removal is finished, with 204 or the refusal.\nfalse answers 202 as soon as the removal is accepted.\n",
            "schema": {
              "type": "string",
              "enum": [
                "true",
                "false"
              ],
              "default": "true"
            }
          }
        ],
        "responses": {
          "202": {
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "description": "Removal accepted (`wait=false`); the account shows its progress in `disconnect`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProviderAccount"
                }
              }
            }
          },
          "204": {
            "description": "Account disconnected and stored credentials removed.",
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/provider-accounts/{account_id}/credentials": {
      "parameters": [
        {
          "$ref": "#/components/parameters/AccountId"
        }
      ],
      "put": {
        "tags": [
          "provider-accounts"
        ],
        "operationId": "replaceProviderCredentials",
        "x-speakeasy-group": "provider_accounts",
        "x-speakeasy-name-override": "replace_credentials",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "summary": "Rotate a connected account's credentials",
        "description": "Replaces a connected account's credentials, for example to rotate a key. Needs the\n`provider-accounts:manage` permission on the API key (a signed-in dashboard session also\nworks) and the account's current `expected_version`.\n\nThe new credentials must belong to the same provider. BoxRouter makes one read-only request\nto the provider and refuses a clear rejection with `422 credentials_rejected`; it does not\ncheck which account the key belongs to. Requests already running keep the old credentials,\nand requests that start afterward use the new ones. A provider that is not enabled for you\nfails with `409 provider_not_enabled`.\n\nLeave out the connection settings to keep the existing ones. Settings you send must match the\nexisting route; changing the endpoint, proxy or header identity needs a new connected\naccount, not a key rotation. Credentials that run your code need extra authority on the key\nand an artifact you uploaded. If the new credentials fail to activate, the old version stays\nin use. A token refresh that already happened with the provider is not undone.\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReplaceCredentials"
              },
              "example": {
                "expected_version": 1,
                "credentials": {
                  "provider": "example-provider",
                  "api_key": "example-api-key-value"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "description": "Account metadata with the incremented credential version.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProviderAccount"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/provider-accounts/{account_id}/test": {
      "parameters": [
        {
          "$ref": "#/components/parameters/AccountId"
        }
      ],
      "post": {
        "tags": [
          "provider-accounts"
        ],
        "operationId": "testProviderAccount",
        "x-speakeasy-group": "provider_accounts",
        "x-speakeasy-name-override": "test",
        "summary": "Test a saved provider account",
        "description": "Requires `provider-accounts:manage` on API keys; dashboard browser sessions are also\nauthorized. The credential check makes one read-only provider request using the saved\ncredentials and returns the provider's native status and body, limited to 4096 characters.\nA successful test can update account health and register provider event webhooks. It\nstarts no sandbox and prepares no image; run the standard image setup to prepare the\nstandard image before the first sandbox needs it. The response reports the credential\ncheck.\nFails with `409 provider_not_enabled` when this provider is not enabled for you.\n",
        "responses": {
          "200": {
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "description": "Raw result of the read-only provider request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProviderAccountTest"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/provider-accounts/{account_id}/standard-image/setup": {
      "parameters": [
        {
          "$ref": "#/components/parameters/AccountId"
        }
      ],
      "post": {
        "tags": [
          "provider-accounts"
        ],
        "operationId": "setupProviderStandardImage",
        "x-speakeasy-group": "provider_accounts",
        "x-speakeasy-name-override": "setup_standard_image",
        "parameters": [
          {
            "$ref": "#/components/parameters/RequiredIdempotencyKey"
          }
        ],
        "summary": "Run the standard image setup proof",
        "description": "Requires `provider-accounts:manage` on API keys; dashboard browser sessions are also\nauthorized. This explicit action first tests the saved key, then boots the provider's\nstandard image, runs a bounded command, and destroys the proof sandbox. The provider\nmay charge for that short sandbox. Readiness is recorded only after boot, command and\ncleanup succeed; failure returns the unavailable state and its setup fix. Requests are\nidempotent and must include an idempotency key.\n",
        "responses": {
          "200": {
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "description": "Current readiness for the exact default-region standard image.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProviderStandardImage"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/operations/{operation_id}": {
      "get": {
        "tags": [
          "operations"
        ],
        "operationId": "getOperation",
        "x-speakeasy-group": "operations",
        "x-speakeasy-name-override": "get",
        "summary": "Get a mutation's known outcome",
        "description": "Read the workspace-owned mutation record identified in an error response.\nThis lookup never repeats the mutation. Unknown remains unknown until\nreconciliation establishes an outcome.\n\nIf a creation response was lost, explicitly resubmitting POST /sandboxes\nin the original workspace with the original Idempotency-Key and identical\neffective request body recovers a retained creation record. Completed\ncreation returns the original sandbox or an error retaining its operation\nID if observing the sandbox's current state fails. An unresolved record\nreturns 409 with its operation ID without dispatching creation again.\nDifferent input returns 409. This POST can create a sandbox if no record\nexists; it is not a read-only lookup. Unknown records remain until resolved;\ncompleted records remain for at least 24 hours. Without the original key and request,\nor beyond guaranteed retention, inspect owned resources or use support\nbefore creating more work. Never change the key to bypass uncertainty.\n",
        "parameters": [
          {
            "name": "operation_id",
            "in": "path",
            "required": true,
            "description": "Durable operation identifier returned by BoxRouter.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "pattern": "^[^\\u0000]*$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Last known outcome; no arbitrary upstream response payloads.",
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Operation"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/volumes": {
      "get": {
        "tags": [
          "volumes"
        ],
        "operationId": "listVolumes",
        "x-speakeasy-group": "volumes",
        "x-speakeasy-name-override": "list",
        "summary": "List volumes",
        "description": "Lists volumes in the caller's workspace using cursor-based pagination. The response includes the current storage usage and live-volume policy only when those values are available.",
        "parameters": [
          {
            "$ref": "#/components/parameters/Cursor"
          },
          {
            "$ref": "#/components/parameters/Limit"
          }
        ],
        "responses": {
          "200": {
            "description": "Volumes",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VolumePage"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "post": {
        "tags": [
          "volumes"
        ],
        "operationId": "createVolume",
        "x-speakeasy-group": "volumes",
        "x-speakeasy-name-override": "create",
        "summary": "Create a volume",
        "description": "The service selects its configured live backend when this workspace's live-volume policy allows creation. Backend identity is neither a request field nor a response label.",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateVolume"
              },
              "example": {
                "name": "project-files"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created volume",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Volume"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "413": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/volumes/{volume_id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/VolumeId"
        }
      ],
      "get": {
        "tags": [
          "volumes"
        ],
        "operationId": "getVolume",
        "x-speakeasy-group": "volumes",
        "x-speakeasy-name-override": "get",
        "summary": "Get a volume",
        "description": "Returns metadata for a BoxRouter-managed volume in the caller's workspace.",
        "responses": {
          "200": {
            "description": "Volume",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Volume"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "delete": {
        "tags": [
          "volumes"
        ],
        "operationId": "deleteVolume",
        "x-speakeasy-group": "volumes",
        "x-speakeasy-name-override": "delete",
        "summary": "Delete a volume and its checkpoints",
        "description": "Deletes a volume and all checkpoint references and stored bytes for it. When the volume's writer is ending (its destroy was accepted), the call waits for the release, at most 120 seconds, before deleting. A running writer fails at once with volume_busy (409). Repeating DELETE retries a pending remote removal and returns 204 when the volume is already deleted. Reuse a supplied Idempotency-Key with the identical request to reconcile an uncertain result; a conflicting active use can return 409.",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "204": {
            "description": "Volume and every checkpoint's bytes deleted."
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/volumes/{volume_id}/checkpoints": {
      "parameters": [
        {
          "$ref": "#/components/parameters/VolumeId"
        }
      ],
      "get": {
        "tags": [
          "volumes"
        ],
        "operationId": "listVolumeCheckpoints",
        "x-speakeasy-group": "volumes",
        "x-speakeasy-name-override": "list_checkpoints",
        "summary": "List volume checkpoints",
        "description": "Lists committed checkpoints for this volume, newest first. A checkpoint created by an in-progress save is not listed until the save commits.",
        "responses": {
          "200": {
            "description": "Checkpoints newest first",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VolumeCheckpointPage"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "post": {
        "tags": [
          "volumes"
        ],
        "operationId": "saveVolume",
        "x-speakeasy-group": "volumes",
        "x-speakeasy-name-override": "save",
        "summary": "Save a volume checkpoint",
        "description": "Saves the current volume filesystem as an immutable checkpoint. The optional sandbox_id identifies the expected writer-lease holder; if omitted, the current holder is used. A mounted branch sandbox can be named to checkpoint its branch files without advancing the source volume's head. Read-only sandboxes cannot save. Reuse a supplied Idempotency-Key with the identical request to reconcile an uncertain response.",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SaveVolume"
              },
              "example": {
                "message": "Before dependency upgrade"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Committed checkpoint",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VolumeCheckpoint"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "413": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/volumes/{volume_id}/checkpoints/{checkpoint}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/VolumeId"
        },
        {
          "name": "checkpoint",
          "in": "path",
          "required": true,
          "schema": {
            "type": "integer",
            "minimum": 1
          }
        }
      ],
      "get": {
        "tags": [
          "volumes"
        ],
        "operationId": "getVolumeCheckpoint",
        "x-speakeasy-group": "volumes",
        "x-speakeasy-name-override": "get_checkpoint",
        "summary": "Get a volume checkpoint",
        "description": "Returns an immutable committed checkpoint by its volume ID and checkpoint number.",
        "responses": {
          "200": {
            "description": "Volume checkpoint",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VolumeCheckpoint"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "delete": {
        "tags": [
          "volumes"
        ],
        "operationId": "deleteVolumeCheckpoint",
        "x-speakeasy-group": "volumes",
        "x-speakeasy-name-override": "delete_checkpoint",
        "summary": "Delete a checkpoint",
        "description": "Removes the checkpoint reference. Backend data is reclaimed when the volume is erased.",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "204": {
            "description": "Checkpoint deleted."
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/volumes/{volume_id}/lease": {
      "parameters": [
        {
          "$ref": "#/components/parameters/VolumeId"
        }
      ],
      "delete": {
        "tags": [
          "volumes"
        ],
        "operationId": "releaseVolumeLease",
        "x-speakeasy-group": "volumes",
        "x-speakeasy-name-override": "release",
        "summary": "Release a volume's writer lease",
        "description": "Releases the volume's writer lease and advances its epoch, invalidating the former writer's lease token. Reuse a supplied Idempotency-Key with the identical request to reconcile an uncertain result.",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "204": {
            "description": "Lease released and its epoch advanced."
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/volumes/{volume_id}/uploads": {
      "parameters": [
        {
          "$ref": "#/components/parameters/VolumeId"
        }
      ],
      "post": {
        "tags": [
          "volumes"
        ],
        "operationId": "createVolumeUpload",
        "x-speakeasy-group": "volumes",
        "x-speakeasy-name-override": "createUpload",
        "summary": "Create a volume file upload",
        "description": "Creates a multipart upload for a file that will appear at\n`/workspace/<path>` in sandboxes. Upload every returned part URL with an\nHTTP PUT containing exactly that part's bytes; save the response `ETag`\nheader for the completion request. Part URLs expire when the session does: six hours\nafter creation plus about one hour for each 70 GiB of the declared size, at most 72 hours;\n`expires_at` says when.\nAn open upload blocks `write` sandboxes, and a live or pending `write`\nattachment blocks uploads (`volume_busy`). `read` and `shared` attachments\nmay coexist, but their sandboxes may need to refresh their volume cache to\nsee the new file.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateVolumeUpload"
              },
              "example": {
                "path": "data/input.csv",
                "size": 1048576
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created multipart upload",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VolumeUpload"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "413": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/volumes/{volume_id}/uploads/{upload_id}/complete": {
      "parameters": [
        {
          "$ref": "#/components/parameters/VolumeId"
        },
        {
          "$ref": "#/components/parameters/UploadId"
        }
      ],
      "post": {
        "tags": [
          "volumes"
        ],
        "operationId": "completeVolumeUpload",
        "x-speakeasy-group": "volumes",
        "x-speakeasy-name-override": "completeUpload",
        "summary": "Complete a volume file upload",
        "description": "Supply each part number exactly once with the `ETag` header returned by its PUT response.",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CompleteVolumeUpload"
              },
              "example": {
                "parts": [
                  {
                    "number": 1,
                    "etag": "\"9b2cf535f27731c974343645a3985328\""
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Completed volume file",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CompletedVolumeUpload"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/volumes/{volume_id}/uploads/{upload_id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/VolumeId"
        },
        {
          "$ref": "#/components/parameters/UploadId"
        }
      ],
      "delete": {
        "tags": [
          "volumes"
        ],
        "operationId": "abortVolumeUpload",
        "x-speakeasy-group": "volumes",
        "x-speakeasy-name-override": "abortUpload",
        "summary": "Abort a volume file upload",
        "description": "Aborts an open multipart upload for this volume. Repeating an abort is safe; the uploaded file is not made visible in the volume.",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "204": {
            "description": "Upload aborted. Repeating an abort is safe."
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/volumes/{volume_id}/downloads": {
      "parameters": [
        {
          "$ref": "#/components/parameters/VolumeId"
        }
      ],
      "post": {
        "tags": [
          "volumes"
        ],
        "operationId": "createVolumeDownload",
        "x-speakeasy-group": "volumes",
        "x-speakeasy-name-override": "createDownload",
        "summary": "Create a volume file download",
        "description": "Creates a temporary download link that expires after one hour.",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateVolumeDownload"
              },
              "example": {
                "path": "data/input.csv"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created download link",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VolumeDownload"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/volumes/{volume_id}/files": {
      "parameters": [
        {
          "$ref": "#/components/parameters/VolumeId"
        }
      ],
      "get": {
        "tags": [
          "volumes"
        ],
        "operationId": "listVolumeFiles",
        "x-speakeasy-group": "volumes",
        "x-speakeasy-name-override": "listFiles",
        "summary": "List files in a volume",
        "description": "Recursively lists files in path order without a directory delimiter. Read and shared sandboxes may need to refresh their volume cache to see new files.",
        "parameters": [
          {
            "name": "prefix",
            "in": "query",
            "description": "Return paths beginning with this relative volume path; may be empty or end in `/`.",
            "schema": {
              "$ref": "#/components/schemas/VolumeFilePrefix"
            }
          },
          {
            "$ref": "#/components/parameters/Cursor"
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Maximum number of files to return.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 1000,
              "default": 100
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Volume files",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VolumeFilePage"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "delete": {
        "tags": [
          "volumes"
        ],
        "operationId": "deleteVolumeFile",
        "x-speakeasy-group": "volumes",
        "x-speakeasy-name-override": "deleteFile",
        "summary": "Delete a volume file",
        "description": "Deletes the file at `path`, or every file under it when `path` ends in `/`, to free space without deleting the volume. Deleting a path that does not exist succeeds, so a repeated request is safe. A live or pending `write` attachment or an open upload makes the volume busy (`volume_busy`); read and shared sandboxes may need to refresh their volume cache to stop seeing the file.",
        "parameters": [
          {
            "name": "path",
            "in": "query",
            "required": true,
            "description": "Relative volume path of one file, or a directory path ending in `/` to delete everything under it.",
            "schema": {
              "$ref": "#/components/schemas/VolumeFilePath"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "File or directory deleted, or it did not exist."
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/sandboxes": {
      "post": {
        "tags": [
          "sandboxes"
        ],
        "operationId": "createSandbox",
        "x-sandbox-provider-spec-next-errors": [
          "no_eligible_route",
          "knob_not_named",
          "unrecognised_word"
        ],
        "x-speakeasy-group": "sandboxes",
        "x-speakeasy-name-override": "create",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "summary": "Create a sandbox",
        "description": "**create (standard image)**\n\nYou can rely on:\n- Sandboxes are created from the requested image.\n\nYou can set: image, lifetime, requirements.\n\n**volume mount**\n\nYou can rely on:\n- The named checkpoint, or the head when none is named, is restored into the mount folder, replacing what the image has there; an empty volume restores nothing.\n\nYou can set: volume.\n\nNot promised: mounting a provider's own volumes.\n\nCreates a sandbox and returns it once it is ready to run commands. Send `{}`, or no\nbody, for the default: the standard image on the best eligible route, running for up\nto 300 seconds. A credit-funded sandbox on a route that can extend a lifetime runs\ninstead for as long as your credit balance covers it when you leave out\n`lifetime_seconds`; `funded_until` on the sandbox says how far it is funded.\n\nDescribe what you need and BoxRouter picks a route that meets all of it:\n\n- `requirements`: capabilities such as `pause_resume`, `previews` or\n  `network_lockdown`, each with the settings you need.\n- `resources`: minimum CPU and memory, and a region.\n- `lifetime_seconds` and `at_end`: how long the sandbox may run, and whether it is\n  destroyed or paused afterward.\n- `preferences`: how to choose among eligible routes (`sort`, `only`, `ignore`,\n  `order`, `allow_fallbacks`).\n- `volume`: a Volume to mount, optionally at a checkpoint.\n- `secret_refs`: saved workspace secrets to add to the environment.\n\nBoxRouter never relaxes a requirement to find a cheaper or faster route. If no route\ncan meet the request, the call fails with `409 no_eligible_route`, `details` names each\nroute that was ruled out and the nearest changes, and nothing is created. A field that\nBoxRouter does not recognize fails with `400 invalid_request`; it is never ignored.\nChoosing a connected account or route whose provider is not enabled for you fails with\n`409 provider_not_enabled` before any route is considered. The response records the\ncontract the sandbox was created under and why its route was chosen.\n\nA created sandbox does not mean your application is listening on a port yet. When one\nattempt's outcome is unclear, such as a timeout before the provider names a sandbox,\nBoxRouter never sends that attempt again: it moves to the next eligible route, unless\n`allow_fallbacks` is false, and destroys any sandbox the unclear attempt makes later. If\nthe outcome of the whole create is unclear, read the operation named by `operation_id`\nto find out what happened.\n\nA `volume` has one writer at a time. If its previous writer is ending (its destroy\nwas accepted, or cleanup of its access is pending), this call waits for the\nrelease, at most 120 seconds, and then creates the sandbox, so you need no polling or\nretry. If the release does not finish in that time, or the writer is still running,\nthe call fails with `409 volume_busy`, outcome `not_started`, and\n`details.writer_sandbox_id` names the writer. A running writer fails at once.\n",
        "requestBody": {
          "required": false,
          "description": "Omission is equivalent to an empty object, which is a baseline sandbox.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateSandbox"
              },
              "examples": {
                "baseline": {
                  "value": {}
                },
                "gates": {
                  "value": {
                    "lifetime_seconds": 1800,
                    "at_end": "pause",
                    "requirements": {
                      "pause_resume": {},
                      "previews": {
                        "access": "public",
                        "ports": [
                          3000
                        ]
                      }
                    },
                    "resources": {
                      "memory_min_mib": 2048,
                      "region": "EU"
                    },
                    "preferences": {
                      "sort": "price"
                    }
                  }
                },
                "connectedProvider": {
                  "description": "Uses a fictional connected account ID; replace it with an account you connected.",
                  "value": {
                    "preferences": {
                      "only": [
                        "example-provider"
                      ]
                    },
                    "route": {
                      "account_id": "acct_example",
                      "supply": "byok"
                    },
                    "env": {
                      "TASK": "example"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Sandbox created and its common runtime is ready.",
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/RequestId"
              },
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Sandbox"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "get": {
        "tags": [
          "sandboxes"
        ],
        "operationId": "listSandboxes",
        "x-speakeasy-group": "sandboxes",
        "x-speakeasy-name-override": "list",
        "summary": "List workspace sandboxes",
        "description": "You can rely on:\n- Lists only the workspace's own sandboxes, each with its latest recorded state.\n- A label filter matches exactly: only sandboxes carrying every requested label are listed.\n\nYou can set: filters, sort, cursor, limit.\n\nNot promised: a fresh observation of each sandbox from its provider.\n\nLists your workspace's sandboxes from BoxRouter's records, without asking providers. `state`\nis the latest state BoxRouter recorded, or `unknown` if it recorded none; get one sandbox to\ncheck its provider live. `observed_at` is when the list was read, and `state_recorded_at` is\nwhen that state was recorded, which can be earlier.\n\n`lifecycle` defaults to `all`; send `lifecycle=live` to list only live sandboxes, or `ended` for\nthe rest. You can repeat the `state` and `provider` parameters to match any\nof several values; repeated `label` parameters must all match. Unknown query parameters fail the request. The page counts apply every\nfilter except `lifecycle`, and `by_state` also ignores `state`, so you can show counts while\nchanging those two filters. `source` filters by what created the sandbox, and a sandbox's\norigin stays readable after it ends or is removed.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/Cursor"
          },
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "name": "lifecycle",
            "in": "query",
            "description": "Include live records, ended records, or both. Defaults to all.",
            "schema": {
              "type": "string",
              "enum": [
                "live",
                "ended",
                "all"
              ],
              "default": "all"
            }
          },
          {
            "name": "state",
            "in": "query",
            "description": "Portable lifecycle state; repeat to select multiple states (OR).",
            "style": "form",
            "explode": true,
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "enum": [
                  "creating",
                  "running",
                  "paused",
                  "destroying",
                  "destroyed",
                  "error",
                  "unknown"
                ]
              }
            }
          },
          {
            "name": "provider",
            "in": "query",
            "description": "Provider ID; repeat to select multiple providers (OR).",
            "style": "form",
            "explode": true,
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "minLength": 1
              }
            }
          },
          {
            "name": "billed_by",
            "in": "query",
            "description": "Filter by upstream billing mode. byok alone includes all connected accounts.",
            "schema": {
              "type": "string",
              "enum": [
                "byok",
                "managed"
              ]
            }
          },
          {
            "name": "account_id",
            "in": "query",
            "description": "Connected account ID; by itself implies billed_by=byok. Invalid with billed_by=managed.",
            "schema": {
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "source",
            "in": "query",
            "description": "Filter by what created the sandbox: github_actions (a BoxRouter Actions job), agents (an agent launch) or api (neither).",
            "schema": {
              "type": "string",
              "enum": [
                "github_actions",
                "agents",
                "api"
              ]
            }
          },
          {
            "name": "actions_run_id",
            "in": "query",
            "description": "Only sandboxes from this BoxRouter Actions run, as in origin.run_id.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 128,
              "pattern": "^[^\\u0000]*$"
            }
          },
          {
            "name": "launch_id",
            "in": "query",
            "description": "Only the sandbox from this agent launch, as in origin.launch_id.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 128,
              "pattern": "^[^\\u0000]*$"
            }
          },
          {
            "name": "label",
            "in": "query",
            "description": "A label the sandbox must carry: key=value matches that exact value (the value may be empty), and a bare key matches any value. Repeat for labels that must all match.",
            "style": "form",
            "explode": true,
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "pattern": "^[^=]+(=.*)?$"
              }
            }
          },
          {
            "name": "created_after",
            "in": "query",
            "description": "Include sandboxes created at or after this RFC 3339 instant.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "created_before",
            "in": "query",
            "description": "Include sandboxes created before this RFC 3339 instant.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "q",
            "in": "query",
            "description": "Match BoxRouter ID prefix, labels.name substring (case-insensitive), or exact provider native ID.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 256
            }
          },
          {
            "name": "sort",
            "in": "query",
            "description": "Sort by creation time or indexed lifetime deadline; newest is the default. For ending_soonest, records with known deadlines sort first by ascending deadline, with BoxRouter ID ascending as the tie-breaker. Records with a null deadline follow in ascending BoxRouter ID order. source groups records by what created them, github_actions first, then agents, then api, newest first within each group.",
            "schema": {
              "type": "string",
              "enum": [
                "newest",
                "oldest",
                "ending_soonest",
                "source"
              ],
              "default": "newest"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of sandboxes belonging to this workspace. A sandbox with no recorded contract, such as one a provider-native route created, carries null `contract`.",
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SandboxPage"
                },
                "examples": {
                  "page": {
                    "summary": "A workspace-scoped sandbox list page",
                    "description": "The account ID in this example is fictional.",
                    "value": {
                      "data": [
                        {
                          "id": "sbx_4f2a",
                          "state": "running",
                          "state_reason": "requested",
                          "failure": null,
                          "native_state": null,
                          "observed_at": "2026-09-29T18:30:00Z",
                          "state_recorded_at": "2026-09-29T18:29:57Z",
                          "created_at": "2026-09-29T17:30:00Z",
                          "expires_at": "2026-09-29T19:30:00Z",
                          "ready_at": "2026-09-29T17:30:04Z",
                          "ended_at": null,
                          "hidden_secrets": null,
                          "tcp_ports": null,
                          "labels": {
                            "name": "checkout-agent",
                            "team": "platform"
                          },
                          "name": "checkout-agent",
                          "resources": {
                            "cpu": 2,
                            "memory_mib": 4096,
                            "disk_mib": null
                          },
                          "image": {
                            "value": "standard",
                            "source": "recorded"
                          },
                          "usage": null,
                          "cost": {
                            "label": "calculated",
                            "total": {
                              "low": "0.0585",
                              "high": "0.0585"
                            }
                          },
                          "lifetime": {
                            "seconds": 7200,
                            "remaining_seconds": 3600,
                            "ends_at": "2026-09-29T19:30:04Z",
                            "kept_until": null,
                            "at_end": "destroy",
                            "max_seconds": 86400,
                            "extendable": false
                          },
                          "route": {
                            "id": "route_01J8ZK2M6D8N4Q7S9T1V3W5X6Y",
                            "provider": "example-provider",
                            "class": null,
                            "adapter_version": "0.3.9",
                            "account_id": "connection:acct_example",
                            "supply": "byok",
                            "native_id": "iukabnkodrn7v36debdoe",
                            "region": "us-east-1",
                            "selection": null
                          },
                          "contract": {
                            "spec_version": "sandbox-provider-spec/0.1",
                            "gates": {},
                            "resources": {
                              "cpu": 2,
                              "memory_mib": 4096,
                              "disk_mib": null,
                              "region": "us-east-1"
                            },
                            "attested": {}
                          },
                          "request": {},
                          "recorder": null,
                          "limits": {
                            "buffered_output_bytes": 16777216,
                            "file_transfer_bytes": 1048576
                          }
                        }
                      ],
                      "next_cursor": null,
                      "counts": {
                        "live": 12,
                        "ended": 3,
                        "by_state": {
                          "running": 8,
                          "paused": 2
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/sandboxes/match": {
      "post": {
        "tags": [
          "sandboxes"
        ],
        "operationId": "matchSandbox",
        "x-speakeasy-group": "sandboxes",
        "x-speakeasy-name-override": "match",
        "x-sandbox-provider-spec-next-errors": [
          "no_eligible_route",
          "knob_not_named",
          "unrecognised_word"
        ],
        "summary": "Explain routing without creating",
        "description": "You can rely on:\n- Evaluates the body exactly as create would and returns the routes create would try, in order, without provisioning, reserving or recording anything.\n\nYou can set: creation body.\n\nNot promised: that a later create finds the same routes eligible.\n\nEach eligible route carries the contract it would grant, every excluded route the\nchecks it failed, and the nearest changes are listed; a later creation checks again.\nA workspace with nothing to match against, that is no provider keys and no credits,\nor a `preferences.only` pin on a provider the workspace has not connected, answers 409 no_eligible_route with the same fix\nPOST /sandboxes gives, because a dry run answers what the creation it stands for\nwould.\n",
        "requestBody": {
          "required": false,
          "description": "The creation body without request-only secret_values; omission is an empty object.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MatchSandbox"
              },
              "example": {
                "resources": {
                  "memory_min_mib": 2048
                },
                "preferences": {
                  "sort": "price"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Routing explanation for this body. An empty eligible list is not an error when candidates were considered and excluded; a workspace with no candidate at all answers 409 no_eligible_route.",
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/RequestId"
              },
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MatchResult"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/sandboxes/{sandbox_id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/SandboxId"
        }
      ],
      "get": {
        "tags": [
          "sandboxes"
        ],
        "operationId": "getSandbox",
        "x-boxrouter-cli-alias": "get",
        "x-speakeasy-group": "sandboxes",
        "x-speakeasy-name-override": "get",
        "summary": "Get a sandbox",
        "description": "You can rely on:\n- Returns a handle for the id, or not_found.\n\nYou can set: sandbox id.\n\nReturns the sandbox with its current state, checked with the provider, without resuming it.\n`observed_at` is when the provider was checked. `state_recorded_at` is when BoxRouter last\nrecorded the state it returns; it is null if a concurrent change replaced the state during\nthe read. `origin` says what created the sandbox and stays readable after the sandbox ends or\nis removed, even when the provider can no longer be checked.\n",
        "responses": {
          "200": {
            "description": "The sandbox, with its account-bound route. A sandbox with no recorded contract, such as one a provider-native route created, carries null `contract`; its route still names the provider and account.",
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Sandbox"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "delete": {
        "tags": [
          "sandboxes"
        ],
        "operationId": "destroySandbox",
        "x-boxrouter-cli-alias": "destroy",
        "x-speakeasy-group": "sandboxes",
        "x-speakeasy-name-override": "destroy",
        "parameters": [
          {
            "name": "discard_unsaved",
            "in": "query",
            "required": false,
            "description": "Destroy even if saving the attached volume fails, discarding unsaved changes.",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "summary": "Destroy a sandbox",
        "description": "You can rely on:\n- Never deletes another generation of the sandbox.\n- Returns once accepted: 204 when confirmed, else 202 with an operation that completes lifecycle work; GET /operations/{id} reports completion.\n- While a destroy is unresolved, a repeated destroy is accepted as the same pending operation and makes no second provider call; once the destroy is confirmed, a repeat returns 204 with no body.\n\nYou can set: nothing.\n\nNot promised: how long teardown takes; that the sandbox is already absent from listings on return.\n\nRequests destruction on the original upstream account, including persistent sandbox\nstorage where the provider's destroy operation removes it. Separately owned volumes\nare not deleted. DELETE returns once the provider accepts the destroy, always as 202\nwith the sandbox: `state` is `destroyed` when the provider confirmed within the request\nand `destroying` while lifecycle work remains, and `operation_id` is set while work\nremains. BoxRouter finishes an accepted destroy without the caller. GET\n/operations/{operation_id} reports the operation's outcome; for an accepted destroy this\nincludes any remaining stop, final usage, and deletion work.\n\nA repeat DELETE while destruction is unresolved returns 202 with the existing\noperation_id and makes no second provider call. Once destruction is confirmed,\nrepeat DELETEs return 202 with the destroyed sandbox and no `operation_id`. Unknown or\nunowned sandbox IDs return 404.\n",
        "responses": {
          "202": {
            "description": "The sandbox after the provider accepted the destroy.",
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Sandbox"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/sandboxes/{sandbox_id}/commands": {
      "parameters": [
        {
          "$ref": "#/components/parameters/SandboxId"
        }
      ],
      "post": {
        "tags": [
          "commands"
        ],
        "operationId": "runCommand",
        "x-speakeasy-group": "commands",
        "x-speakeasy-name-override": "run",
        "x-boxrouter-result-check": {
          "error": "CommandFailed",
          "message": "Command failed: exit_code={exit_code}, timed_out={timed_out}",
          "fail_when_any": [
            {
              "field": "exit_code",
              "not_equal": 0
            },
            {
              "field": "timed_out",
              "equal": true
            }
          ],
          "error_fields": [
            "exit_code",
            "stdout",
            "stderr",
            "timed_out"
          ]
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "summary": "Run a buffered command",
        "description": "**Commands**\n\nYou can rely on:\n- Runs in a login Bash, so PATH changes that installers write to ~/.profile apply to later commands.\n- Returns the exit status.\n- Returns stdout and stderr separately.\n- Returns exact bytes in byte mode.\n- The timeout ends the command.\n- On a timeout the command's process group receives TERM at the deadline and KILL 5 seconds later, in both output modes.\n- Returned output is captured after the shell exits, and later writes by background children cannot change it.\n- An uncertain outcome is never replayed.\n- Output over the limit returns the exit status and the first output_limit_bytes of each stream, marked truncated. Default and maximum: 512 KiB per stream. Processes stream complete large output.\n\nYou can set: command, cwd, env, timeout_seconds, output (text or bytes), output_limit_bytes.\n\nNot promised: guest disk used by output above the limit; ending children that leave the command's process group (for example setsid daemons).\n\n**Command stdin**\n\nYou can rely on:\n- A command takes no input: it starts with stdin at end-of-file, and login profiles, the command and its children all read empty input.\n\nYou can set: nothing (use process input for interactive input).\n\nOutput over output_limit_bytes is not an error: the result sets stdout_truncated or\nstderr_truncated. A nonzero exit is a completed workload result, not an HTTP failure.\nA command that reaches timeout_seconds is a result too: the process group is ended and\nthe answer is 200 with timed_out true, exit_code null and the output written so far.\n504 timeout is left for the case where BoxRouter lost sight of the command and cannot\nsay whether it ran. A disconnected HTTP client is not promised to end the command; the\ntimeout ends it. Use process streaming for output without a bound.\nGenerated clients take an opt-in check argument and raise CommandFailed (the operation's\nx-boxrouter-result-check) when exit_code is not 0 or timed_out is true.\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RunCommand"
              },
              "example": {
                "command": "printf hello",
                "timeout_seconds": 60
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Command exited or reached its timeout; stdout and stderr are separate and hold everything it wrote, up to the limit.",
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/CommandResult"
                    },
                    {
                      "$ref": "#/components/schemas/ByteCommandResult"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/sandboxes/{sandbox_id}/files/content": {
      "parameters": [
        {
          "$ref": "#/components/parameters/SandboxId"
        },
        {
          "name": "path",
          "in": "query",
          "required": true,
          "description": "Absolute path inside the sandbox. Encoded as a query value, never a host path.",
          "schema": {
            "type": "string",
            "minLength": 1,
            "pattern": "^/[^\\u0000]*$"
          }
        }
      ],
      "get": {
        "tags": [
          "files"
        ],
        "operationId": "readFile",
        "x-boxrouter-cli-alias": "read",
        "x-speakeasy-group": "files",
        "x-speakeasy-name-override": "read",
        "summary": "Read exact file bytes",
        "description": "You can rely on:\n- Returns complete bytes, or resource_limit with no prefix returned.\n- Reading a directory or another path that is not a regular file fails and returns no data.\n- An absent path is not_found, outcome failed: a read has no effect, so its outcome is never unknown.\n\nYou can set: path.\n\nNot promised: consistency while another writer changes the file.\n\nThe limit is the advertised limits.file_transfer_bytes. Bytes are not text-decoded.\nClosing the transfer does not destroy the sandbox. A stream that ends before\nContent-Length is an incomplete transfer, not a successful file read.\n",
        "responses": {
          "200": {
            "description": "File bytes. Empty files have an empty response body.",
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              },
              "Content-Length": {
                "description": "Total expected bytes when known before streaming.",
                "schema": {
                  "type": "integer",
                  "minimum": 0
                }
              }
            },
            "content": {
              "application/octet-stream": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "413": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "put": {
        "tags": [
          "files"
        ],
        "operationId": "writeFile",
        "x-boxrouter-cli-alias": "write",
        "x-speakeasy-group": "files",
        "x-speakeasy-name-override": "write",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "summary": "Write exact file bytes",
        "description": "You can rely on:\n- Writes exact bytes.\n- Creates missing parents.\n- A new file is readable and writable by the command user.\n- The size limit is enforced.\n\nYou can set: path, data.\n\nNot promised: owner, mode or executable bit; atomic replace; whether a symbolic link at the path is followed or replaced.\n\nThe limit is the advertised limits.file_transfer_bytes. A failed transfer may leave\npartial data; the error's outcome describes what is known. SDK text helpers must encode\ntext as UTF-8 before transfer.\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/octet-stream": {
              "schema": {
                "type": "string",
                "format": "binary"
              },
              "example": "hello world\n"
            }
          }
        },
        "responses": {
          "204": {
            "description": "All bytes written successfully.",
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "413": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/sandboxes/{sandbox_id}/files/uploads": {
      "parameters": [
        {
          "$ref": "#/components/parameters/SandboxId"
        }
      ],
      "post": {
        "tags": [
          "files"
        ],
        "operationId": "createSandboxUpload",
        "x-boxrouter-switch": "sandbox_file_transfers",
        "x-speakeasy-group": "files",
        "x-speakeasy-name-override": "createUpload",
        "summary": "Create a sandbox file upload",
        "description": "You can rely on:\n- A completed upload leaves exactly the declared bytes at the path; a body of another length is refused.\n\nYou can set: path, size.\n\nNot promised: removing bytes already written when an upload is aborted.\n\nStarts an upload of a file of known size to an absolute path in a running sandbox. Send\nevery returned part as described by its `TransferPart`, then call `completeSandboxUpload`\nwith each part's response `ETag`, if any. BoxRouter chooses the `route`; it is\ninformational and clients must not branch on it. Upload links and the session last up to\nsix hours after creation; `expires_at` says when they end. Launch behaviour is always\nexactly one part. Idempotency-Key is required on create, complete and abort; repeat an\nuncertain call with the same key.\n\nNeeds the sandbox file transfer switch. While the switch is off, which is the default, the\ncall is refused with `422 unsupported_feature`. Inline file reads and writes are not affected.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/TransferIdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateSandboxUpload"
              },
              "example": {
                "path": "/workspace/data.bin",
                "size": 1048576
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created upload",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SandboxUpload"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "413": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/sandboxes/{sandbox_id}/files/uploads/{upload_id}/complete": {
      "parameters": [
        {
          "$ref": "#/components/parameters/SandboxId"
        },
        {
          "$ref": "#/components/parameters/SandboxUploadId"
        }
      ],
      "post": {
        "tags": [
          "files"
        ],
        "operationId": "completeSandboxUpload",
        "x-boxrouter-switch": "sandbox_file_transfers",
        "x-speakeasy-group": "files",
        "x-speakeasy-name-override": "completeUpload",
        "summary": "Complete a sandbox file upload",
        "description": "You can rely on:\n- A completed upload leaves exactly the declared bytes at the path; a body of another length is refused.\n\nYou can set: path, size.\n\nNot promised: removing bytes already written when an upload is aborted.\n\nSupply each part number exactly once with the `ETag` header returned by its request, if\nit returned one. Repeating the call with the same idempotency key returns the same result.\n\nNeeds the sandbox file transfer switch. While the switch is off, which is the default, the\ncall is refused with `422 unsupported_feature`. Inline file reads and writes are not affected.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/TransferIdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CompleteSandboxUpload"
              },
              "example": {
                "parts": [
                  {
                    "number": 1,
                    "etag": "\"9b2cf535f27731c974343645a3985328\""
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Completed file",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CompletedSandboxUpload"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/sandboxes/{sandbox_id}/files/uploads/{upload_id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/SandboxId"
        },
        {
          "$ref": "#/components/parameters/SandboxUploadId"
        }
      ],
      "delete": {
        "tags": [
          "files"
        ],
        "operationId": "abortSandboxUpload",
        "x-boxrouter-switch": "sandbox_file_transfers",
        "x-speakeasy-group": "files",
        "x-speakeasy-name-override": "abortUpload",
        "summary": "Abort a sandbox file upload",
        "description": "You can rely on:\n- A completed upload leaves exactly the declared bytes at the path; a body of another length is refused.\n\nYou can set: path, size.\n\nNot promised: removing bytes already written when an upload is aborted.\n\nIdempotent.\n\nNeeds the sandbox file transfer switch. While the switch is off, which is the default, the\ncall is refused with `422 unsupported_feature`. Inline file reads and writes are not affected.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/TransferIdempotencyKey"
          }
        ],
        "responses": {
          "204": {
            "description": "Upload aborted. Repeating an abort is safe."
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/sandboxes/{sandbox_id}/files/downloads": {
      "parameters": [
        {
          "$ref": "#/components/parameters/SandboxId"
        }
      ],
      "post": {
        "tags": [
          "files"
        ],
        "operationId": "createSandboxDownload",
        "x-boxrouter-switch": "sandbox_file_transfers",
        "x-speakeasy-group": "files",
        "x-speakeasy-name-override": "createDownload",
        "summary": "Create a sandbox file download",
        "description": "You can rely on:\n- A complete download returns exactly the file's bytes; a transfer that ends short fails instead of returning a prefix.\n\nYou can set: path.\n\nNot promised: the file's size before the download starts.\n\nCreates a temporary download link for a file in a running sandbox. The link lasts up to\none hour after creation; `expires_at` says when it ends. `route` is informational and\nclients must not branch on it.\n\nNeeds the sandbox file transfer switch. While the switch is off, which is the default, the\ncall is refused with `422 unsupported_feature`. Inline file reads and writes are not affected.\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateSandboxDownload"
              },
              "example": {
                "path": "/workspace/results.json"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created download; `content` carries the body inline when `inline_below` admits it, otherwise the link fields do",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SandboxDownload"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "413": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/sandboxes/{sandbox_id}/files/directories": {
      "parameters": [
        {
          "$ref": "#/components/parameters/SandboxId"
        }
      ],
      "get": {
        "tags": [
          "files"
        ],
        "operationId": "listDirectory",
        "x-speakeasy-group": "files",
        "x-speakeasy-name-override": "list",
        "summary": "List the immediate entries of a directory",
        "description": "You can rely on:\n- Returns every immediate entry, including hidden ones and broken symbolic links, sorted by name.\n- Each entry has its type (file, directory, symlink, other); a link is not followed.\n- More entries than the advertised limit fail; the list is never truncated.\n\nYou can set: path.\n\nNot promised: metadata beyond the type; a consistent snapshot while the directory changes.\n\nAn unreadable or missing directory fails; it does not appear empty. No recursion.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/Path"
          }
        ],
        "responses": {
          "200": {
            "description": "Every immediate entry, sorted by name; an empty directory returns an empty array.",
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/DirectoryEntry"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "post": {
        "tags": [
          "files"
        ],
        "operationId": "createDirectory",
        "x-speakeasy-group": "files",
        "x-speakeasy-name-override": "mkdir",
        "summary": "Create a directory",
        "description": "You can rely on:\n- parents=true (the default) creates missing parents and accepts an existing directory.\n- parents=false requires the parent and refuses an existing path.\n\nYou can set: path, parents.\n\nNot promised: mode and owner beyond command-user usability.\n\nA failure may leave some parent directories created. An uncertain mutation is never automatically replayed.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateDirectoryRequest"
              },
              "example": {
                "path": "/workspace/output",
                "parents": true
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "Directory creation completed.",
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/sandboxes/{sandbox_id}/files/exists": {
      "parameters": [
        {
          "$ref": "#/components/parameters/SandboxId"
        }
      ],
      "get": {
        "tags": [
          "files"
        ],
        "operationId": "pathExists",
        "x-speakeasy-group": "files",
        "x-speakeasy-name-override": "exists",
        "summary": "Check for an accessible filesystem target",
        "description": "You can rely on:\n- Follows symbolic links. True when the target exists; false when it is missing, the link is broken, or the target is not accessible.\n- A failure to check raises an error; it never reads as false.\n\nYou can set: path.\n\nNot promised: whether the answer still holds after the call.\n\nTransport and command-startup failures remain errors. This read does not reserve the path or guarantee it remains present.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/Path"
          }
        ],
        "responses": {
          "200": {
            "description": "Whether the accessible target exists.",
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "boolean"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/sandboxes/{sandbox_id}/files/remove": {
      "parameters": [
        {
          "$ref": "#/components/parameters/SandboxId"
        }
      ],
      "post": {
        "tags": [
          "files"
        ],
        "operationId": "removePath",
        "x-speakeasy-group": "files",
        "x-speakeasy-name-override": "remove",
        "summary": "Remove a file, symbolic link or directory",
        "description": "You can rely on:\n- Removes only the named entry.\n- A nonempty directory needs recursive.\n- A symbolic link, broken or not, is unlinked and its target kept.\n- A missing path fails.\n- The sandbox root is refused.\n\nYou can set: path, recursive.\n\nNot promised: atomicity; partial progress after a failure.\n\nA final slash does not change which entry is removed. Failures may leave partial changes. An uncertain mutation is never automatically replayed.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RemovePathRequest"
              },
              "example": {
                "path": "/workspace/output",
                "recursive": true
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "Removal completed.",
            "headers": {
              "Server-Timing": {
                "$ref": "#/components/headers/ServerTiming"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/price-versions": {
      "get": {
        "tags": [
          "pricing"
        ],
        "operationId": "listPriceVersions",
        "x-speakeasy-group": "pricing",
        "x-speakeasy-name-override": "versions",
        "summary": "List the providers' live price versions",
        "description": "Public: needs no key or session. Lists every live price version, which is what\nBoxRouter used to calculate sandbox costs, so a published cost can be\nrechecked without BoxRouter's database. Live versions never change. With `at`, returns\nonly the version in effect at that time, one per provider; a provider with no version\nin effect then is left out. Effective periods include `effective_from` and exclude\n`effective_to` (`[effective_from, effective_to)`); the version taking over at a boundary\napplies at that instant.\n",
        "security": [],
        "parameters": [
          {
            "name": "provider",
            "in": "query",
            "description": "Only this provider's versions.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 64,
              "pattern": "^[a-z][a-z0-9-]*$"
            }
          },
          {
            "name": "at",
            "in": "query",
            "description": "Only the version in effect at this time.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Live price versions.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PriceVersionPage"
                },
                "examples": {
                  "e2b": {
                    "summary": "E2B's version, from its pricing page",
                    "value": {
                      "data": [
                        {
                          "provider": "e2b",
                          "version": "e2b@2026-09-29",
                          "effective_from": "2026-09-29T00:00:00Z",
                          "effective_to": null,
                          "last_confirmed_at": "2026-10-03T06:14:09Z",
                          "document": {
                            "provider": "e2b",
                            "version": "e2b@2026-09-29",
                            "effective_from": "2026-09-29T00:00:00Z",
                            "retrieved_at": "2026-09-29T22:52:36Z",
                            "boundary": {
                              "start": "provider",
                              "end": "provider",
                              "checked": false,
                              "evidence": null
                            },
                            "sources": [
                              {
                                "url": "https://e2b.dev/pricing",
                                "quote": "We charge per second of a running sandbox."
                              },
                              {
                                "url": "https://e2b.dev/pricing",
                                "quote": "vCPUs Plan Costs 1 Hobby / Pro $0.000014/s 2 [Default] Hobby / Pro $0.000028/s 4 Hobby / Pro $0.000056/s 6 Hobby / Pro $0.000084/s 8 Hobby / Pro $0.000112/s"
                              },
                              {
                                "url": "https://e2b.dev/pricing",
                                "quote": "Memory (GiB) Plan Costs 1 Hobby / Pro $0.0000045/s 2 Hobby / Pro $0.0000090/s 4 [Default] Hobby / Pro $0.0000180/s 8 Hobby / Pro $0.0000360/s"
                              },
                              {
                                "url": "https://e2b.dev/pricing",
                                "quote": "Storage (GiB) Plan Costs 10 Hobby Free 20 Pro Free"
                              },
                              {
                                "url": "https://e2b.dev/pricing",
                                "quote": "Hobby FREE /$100 of usage in credits + Usage Costs"
                              },
                              {
                                "url": "https://e2b.dev/pricing",
                                "quote": "pro $150 /month + Usage Costs"
                              },
                              {
                                "url": "https://e2b.dev/pricing",
                                "quote": "Pro+ — 600 concurrent +$500/mo Pro++ — 1,100 concurrent +$1,000/mo"
                              },
                              {
                                "url": "https://e2b.dev/pricing",
                                "quote": "Enterprise requires $3,000/mo minimum."
                              },
                              {
                                "url": "https://docs.e2b.dev/billing",
                                "quote": "You pay per second for compute resources while your sandbox is running."
                              },
                              {
                                "url": "https://docs.e2b.dev/billing",
                                "quote": "Do I pay for stopped sandboxes? No. You only pay while a sandbox is actively running. Once a sandbox is paused, killed or times out, billing stops immediately."
                              }
                            ],
                            "classes": [
                              {
                                "name": "default",
                                "default": true,
                                "rates": {
                                  "cpu": {
                                    "usd": "0.000014",
                                    "per": "vcpu-second"
                                  },
                                  "memory": {
                                    "usd": "0.0000045",
                                    "per": "gib-second"
                                  }
                                },
                                "meter": {
                                  "cpu": {
                                    "basis": "allocated",
                                    "billed_states": [
                                      "running"
                                    ]
                                  },
                                  "memory": {
                                    "basis": "allocated",
                                    "billed_states": [
                                      "running"
                                    ]
                                  }
                                }
                              }
                            ],
                            "exclusions": [
                              "Plan fees: Hobby $0 a month, Pro $150 a month, Enterprise custom with a $3,000 a month minimum.",
                              "Concurrency add-ons on Pro: Pro+ (600 concurrent sandboxes) $500 a month, Pro++ (1,100) $1,000 a month.",
                              "Credits: Hobby includes a one-time $100 usage credit, which list prices do not apply.",
                              "Storage: free, 10 GiB on Hobby and 20 GiB on Pro; no separate storage rate is published."
                            ],
                            "open_questions": [
                              "The pages never say in words whether the meter is allocated or used CPU and RAM; both price tables are keyed by configured size, so allocation is assumed.",
                              "Charges for egress, template builds and template storage are not published anywhere read; absence is not confirmation that they are free."
                            ]
                          }
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/providers": {
      "get": {
        "tags": [
          "providers"
        ],
        "operationId": "listProviders",
        "x-speakeasy-group": "providers",
        "x-speakeasy-name-override": "list",
        "summary": "List available provider routes",
        "description": "Returns only supply visible to the caller, including account-specific\nentitlements and limits. This is a point-in-time eligibility view, not a\ncapacity reservation. Unknown or unverified capability guarantees are not\nadvertised as supported. Server-side eligibility is rechecked at creation.\n",
        "responses": {
          "200": {
            "description": "Routes available to this workspace.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProviderPage"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "BrowserSession": {
        "type": "apiKey",
        "in": "cookie",
        "name": "__Host-boxrouter_session",
        "description": "HttpOnly server-side session. Local HTTP uses boxrouter_session. Browser mutations require the session CSRF token and the configured Origin; execution API keys cannot administer sessions or customer keys."
      },
      "BoxRouterKey": {
        "type": "http",
        "scheme": "bearer",
        "description": "BoxRouter API key; never an upstream provider key."
      },
      "GitHubWebhookSignature": {
        "type": "apiKey",
        "in": "header",
        "name": "X-Hub-Signature-256",
        "description": "HMAC-SHA256 signature from the shared GitHub App; verify against the original raw request bytes before JSON parsing."
      }
    },
    "schemas": {
      "AgentPage": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "agents"
        ],
        "properties": {
          "agents": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Agent"
            }
          }
        }
      },
      "Agent": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "name",
          "display_name",
          "description",
          "secrets",
          "ports"
        ],
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 63,
            "pattern": "^[a-z][a-z0-9-]{0,62}$"
          },
          "display_name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128,
            "description": "The agent's human-facing name."
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "secrets": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SecretName"
            }
          },
          "interactive": {
            "type": "boolean",
            "default": true
          },
          "preinstalled": {
            "type": "boolean",
            "default": false,
            "description": "The launch runs on an image that already carries this agent's harness."
          },
          "required_env": {
            "$ref": "#/components/schemas/AgentRequiredEnvironment"
          },
          "max_copies": {
            "$ref": "#/components/schemas/AgentMaximumCopies"
          },
          "model_access": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ModelAccess"
            }
          },
          "sign_in": {
            "type": "string",
            "minLength": 1,
            "maxLength": 256
          },
          "ports": {
            "type": "array",
            "items": {
              "type": "integer",
              "minimum": 1,
              "maximum": 65535
            }
          }
        }
      },
      "SecretName": {
        "type": "string",
        "minLength": 1,
        "maxLength": 128,
        "pattern": "^[A-Z][A-Z0-9_]{0,127}$"
      },
      "AgentRequiredEnvironment": {
        "type": "array",
        "default": [],
        "items": {
          "$ref": "#/components/schemas/AgentEnvironmentRequirement"
        },
        "description": "Names of environment variables that must have nonblank values when launching the agent. BoxRouter checks them after merging env overrides and resolving credentials, before reservation. Values remain unchanged; this does not verify an external session or credential."
      },
      "AgentEnvironmentRequirement": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "name"
        ],
        "properties": {
          "name": {
            "type": "string",
            "pattern": "^[A-Za-z_][A-Za-z0-9_]*$"
          },
          "description": {
            "type": "string",
            "minLength": 1,
            "maxLength": 1024,
            "description": "Plain-text setup guidance, never an input value or executable markup."
          }
        }
      },
      "AgentMaximumCopies": {
        "type": "integer",
        "minimum": 1,
        "description": "Maximum copies of this resolved manifest in one launch run. Omission adds no manifest-specific ceiling. Interactive manifests remain ineligible for launch runs."
      },
      "ModelAccess": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "secret",
          "provider",
          "label"
        ],
        "properties": {
          "secret": {
            "$ref": "#/components/schemas/SecretName"
          },
          "provider": {
            "type": "string",
            "enum": [
              "openai",
              "anthropic",
              "openrouter",
              "cursor"
            ],
            "x-boxrouter-open-enum": true
          },
          "label": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128
          }
        }
      },
      "ApiErrorResponse": {
        "type": "object",
        "required": [
          "error"
        ],
        "description": "The one error body every failing call answers. It leads with what to do: `retry` says whether to send the call again, `fix` says what to change, `outcome` says what happened, and `doc_url` links to the page that explains the code. Clients retry `retry: safe` for you with the same idempotency key.",
        "x-sandbox-provider-spec-codes": [
          "no_eligible_route",
          "knob_not_named",
          "unrecognised_word",
          "invalid_request",
          "not_named",
          "gate_unavailable",
          "account_unhealthy",
          "lifetime_limit",
          "lifetime_used_up",
          "not_running",
          "invalid_state",
          "sandbox_ended",
          "not_found",
          "provider_error",
          "timeout",
          "contract_violation"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "code",
              "message",
              "request_id",
              "outcome",
              "retry",
              "retry_after_seconds"
            ],
            "properties": {
              "code": {
                "type": "string",
                "description": "Stable machine category. Operation failures use SandboxProviderSpec error codes,\nincluding invalid_request, invalid_state, not_found, unauthorized,\nincompatible_requirements, no_eligible_route, capacity_unavailable,\ncapability_unavailable, contract_violation, resource_limit, timeout and\nprovider_error. Hosted service failures add method_not_allowed,\nunauthenticated, forbidden, actions_sandbox_protected,\ninsufficient_credit, spend_limit_exceeded,\nprovider_not_enabled, credentials_rejected, conflict, rate_limited, provider_quota, request_timeout, overloaded,\ndatabase_unavailable, payment_method_required, payment_declined, promotion_already_redeemed, account_exists, and internal_error. unsupported_feature and\noutput_limit are earlier names still returned by some routes.\nOrganization and membership operations also use organization_changed, last_admin,\nstale_membership, directory_managed and change_in_progress. Key ownership and\ninvitation operations use idempotency_key_reused and conflict.\nCredit refunds and purchase quotes also use refund_window_closed,\nnothing_to_refund, refund_below_minimum, refund_in_progress,\npurchase_in_progress, dispute_open, already_refunded,\nrefund_amount_changed, refund_fee_unavailable, quote_changed,\nsession_required, refund_daily_limit, refund_rate_limit,\nrefund_retry_requires_support, idempotency_key_reused and fraud_review.\nCard setup adds card_setup_rate_limit (429, with Retry-After): a workspace may start five\ncard setups an hour.\nA provider that refuses the request for its own plan or quota limit answers\n429 provider_quota with the provider's words in native_message; rate_limited is\nBoxRouter's own limit.\nRouting Prevent Overrides refuses a request containing preferences.order,\npreferences.sort or preferences.allow_fallbacks with routing_overrides_forbidden,\noutcome not_started and details.fields naming the prohibited inputs. No provider\neffect occurs.\nLaunch operations also use invalid_request, secret_missing, agent_not_found,\nno_eligible_route and launch_failed.\nA process or terminal is observed by one API task. When that task stops, process\noutput, result and stdin answer 410 process_observer_lost (reading or cancelling the\nprocess still works), and a terminal on a provider that cannot reattach it answers\n410 terminal_observer_lost. invalid_observer_hop (403) refuses an internal hop\nbetween API tasks that is not signed; clients never send one.\nOpening a preview that the provider answered with other access than the request\nasked for returns 502 preview_access_refused: that preview is never returned, and\ndetails say whether it was ended.\nStarting a process with wait_for_port answers 409 port_not_listening, outcome partial,\nwhen the process exits before the port accepts connections or the port stays closed for\n30 seconds; the process is ended and details carry the output so far.\nA request that must store content (a volume, a saved artifact) under transient content\nretention answers 409 privacy_persistence_conflict with outcome not_started.\nA sandbox request that stops before anything is created also answers\nlifetime_cap_exceeded, knob_not_named and unrecognised_word (400), and price_unknown and\npolicy_denied (409), each with outcome not_started; the Actions codes job_claim_lost,\nactions_authority_changed, actions_candidate_ceiling_withdrawn and\nactions_candidate_outside_ceiling (409) say the job's claim, settings or admitted routes\nchanged; provider_budget_exhausted (409) says a run's provider budget allows no\nfurther create. A create that names an image Cloud cannot use answers 400\nimage_architecture_unsupported, image_digest_resolution_failed,\nimage_preparation_unsupported or private_image_managed_route_unavailable, and\nprivacy_admission_unavailable when privacy cannot be enforced; each says what to change.\nLaunch and source-repository refusals name the repository or manifest fault (code_ref_not_found,\ncode_repository_*, source_*, invalid_source_manifest, invalid_manifest_encoding,\ninvalid_run_spec, repository_*, reserved_env_refused, launch_run_position_conflict,\ncode_reference_moved, dockerfile_context_unsupported, image_tag_unresolved,\nrecovery_sandbox_mismatch); the GitHub-side ones (source_rate_limited,\nsource_resolution_failed, source_resolution_timeout, code_repository_resolution_failed)\nare safe to resend. image_setup_timeout, managed_funding_unavailable,\nlifetime_funding_conflict, candidate_admission_unavailable, secrets_unavailable and the\nActions candidate codes (actions_candidate_record_invalid, actions_create_budget_exhausted,\nactions_create_format_mismatch) complete the creation and extension refusals.\ndispatch_limit_reached, inline_secret_values_refused and launch_incomplete come from\nlaunch runs, provider_policy_unknown from an operation whose privacy evidence cannot be\nverified, and quota_exceeded from a full managed provider account.\nVolume operations also use volume_busy, volume_lease_lost, volume_not_attached,\nvolume_incompatible, volume_save_failed and volume_restore_failed. Creating a\nsandbox on a volume whose writer is ending waits for the release (at most 120\nseconds) before it can answer volume_busy.\nA team member's new personal API key is paused until WorkOS membership sync catches\nup: it answers 403 forbidden whose message and fix say the key becomes active once\nthe team membership syncs, usually within a minute, and the call can be retried.\nClients must preserve and handle unknown categories explicitly.\n",
                "x-boxrouter-error-codes": {
                  "account_exists": [
                    409
                  ],
                  "account_unhealthy": [
                    402
                  ],
                  "actions_authority_changed": [
                    409
                  ],
                  "actions_candidate_ceiling_withdrawn": [
                    409
                  ],
                  "actions_candidate_outside_ceiling": [
                    409
                  ],
                  "actions_candidate_record_invalid": [
                    409
                  ],
                  "actions_create_budget_exhausted": [
                    409
                  ],
                  "actions_create_format_mismatch": [
                    409
                  ],
                  "actions_sandbox_protected": [
                    403
                  ],
                  "agent_not_found": [
                    404
                  ],
                  "already_refunded": [
                    409
                  ],
                  "authorization_error": [
                    403
                  ],
                  "candidate_admission_unavailable": [
                    503
                  ],
                  "capability_unavailable": [
                    409,
                    503
                  ],
                  "capability_unverified": [
                    409
                  ],
                  "card_setup_rate_limit": [
                    429
                  ],
                  "change_in_progress": [
                    409
                  ],
                  "code_ref_not_found": [
                    404
                  ],
                  "code_reference_moved": [
                    409
                  ],
                  "code_repository_not_authorized": [
                    403
                  ],
                  "code_repository_not_found": [
                    404
                  ],
                  "code_repository_not_private": [
                    400
                  ],
                  "code_repository_not_public": [
                    404
                  ],
                  "code_repository_resolution_failed": [
                    502
                  ],
                  "command_failed": [
                    409
                  ],
                  "command_observation_busy": [
                    409
                  ],
                  "conflict": [
                    409
                  ],
                  "contract_violation": [
                    409
                  ],
                  "credentials_rejected": [
                    409,
                    422
                  ],
                  "database_unavailable": [
                    503
                  ],
                  "directory_managed": [
                    409
                  ],
                  "dispatch_limit_reached": [
                    409
                  ],
                  "dispute_open": [
                    409
                  ],
                  "dockerfile_context_unsupported": [
                    400
                  ],
                  "expired": [
                    410
                  ],
                  "forbidden": [
                    403
                  ],
                  "fraud_review": [
                    409
                  ],
                  "gate_unavailable": [
                    409
                  ],
                  "idempotency_key_reused": [
                    409,
                    422
                  ],
                  "identity_unavailable": [
                    503
                  ],
                  "image_architecture_unsupported": [
                    400
                  ],
                  "image_digest_resolution_failed": [
                    400
                  ],
                  "image_preparation_unsupported": [
                    400
                  ],
                  "image_setup_timeout": [
                    504
                  ],
                  "image_tag_unresolved": [
                    400
                  ],
                  "inline_secret_values_refused": [
                    422
                  ],
                  "insufficient_credit": [
                    402
                  ],
                  "internal_error": [
                    500
                  ],
                  "invalid_manifest_encoding": [
                    400
                  ],
                  "invalid_observer_hop": [
                    403
                  ],
                  "invalid_request": [
                    400,
                    413,
                    422,
                    428
                  ],
                  "invalid_run_spec": [
                    400
                  ],
                  "invalid_source_manifest": [
                    400
                  ],
                  "invalid_state": [
                    409
                  ],
                  "job_claim_lost": [
                    409
                  ],
                  "knob_not_named": [
                    400
                  ],
                  "last_admin": [
                    409
                  ],
                  "launch_failed": [
                    409
                  ],
                  "launch_incomplete": [
                    409
                  ],
                  "launch_run_position_conflict": [
                    409
                  ],
                  "lifetime_cap_exceeded": [
                    400
                  ],
                  "lifetime_funding_conflict": [
                    409
                  ],
                  "lifetime_limit": [
                    409
                  ],
                  "lifetime_used_up": [
                    409
                  ],
                  "managed_funding_unavailable": [
                    503
                  ],
                  "method_not_allowed": [
                    405
                  ],
                  "no_eligible_route": [
                    409
                  ],
                  "not_found": [
                    404
                  ],
                  "not_named": [
                    409
                  ],
                  "not_running": [
                    409
                  ],
                  "nothing_to_refund": [
                    409
                  ],
                  "organization_changed": [
                    409
                  ],
                  "output_limit": [
                    413
                  ],
                  "overloaded": [
                    503
                  ],
                  "payment_declined": [
                    402
                  ],
                  "payment_method_required": [
                    409
                  ],
                  "payment_provider_rejected": [
                    502
                  ],
                  "payment_provider_unavailable": [
                    503
                  ],
                  "payments_unavailable": [
                    503
                  ],
                  "policy_denied": [
                    409
                  ],
                  "port_not_listening": [
                    409
                  ],
                  "preview_access_refused": [
                    502
                  ],
                  "price_unknown": [
                    409
                  ],
                  "privacy_admission_unavailable": [
                    400
                  ],
                  "privacy_persistence_conflict": [
                    409
                  ],
                  "private_image_managed_route_unavailable": [
                    400
                  ],
                  "process_observer_lost": [
                    410
                  ],
                  "promotion_already_redeemed": [
                    409
                  ],
                  "promotion_code_invalid": [
                    404
                  ],
                  "provider_budget_exhausted": [
                    409
                  ],
                  "provider_error": [
                    502
                  ],
                  "provider_not_enabled": [
                    409
                  ],
                  "provider_policy_unknown": [
                    409
                  ],
                  "provider_quota": [
                    429
                  ],
                  "purchase_in_progress": [
                    409
                  ],
                  "quota_exceeded": [
                    429
                  ],
                  "quote_changed": [
                    409
                  ],
                  "rate_limited": [
                    429
                  ],
                  "recovery_sandbox_mismatch": [
                    409
                  ],
                  "refund_amount_changed": [
                    409
                  ],
                  "refund_below_minimum": [
                    409
                  ],
                  "refund_daily_limit": [
                    429
                  ],
                  "refund_fee_unavailable": [
                    409
                  ],
                  "refund_in_progress": [
                    409
                  ],
                  "refund_rate_limit": [
                    429
                  ],
                  "refund_retry_requires_support": [
                    409
                  ],
                  "refund_window_closed": [
                    409
                  ],
                  "repository_file_unsupported": [
                    400
                  ],
                  "repository_too_large": [
                    400
                  ],
                  "request_timeout": [
                    408
                  ],
                  "reserved_env_refused": [
                    400,
                    422
                  ],
                  "resource_limit": [
                    413,
                    507
                  ],
                  "routing_overrides_forbidden": [
                    400
                  ],
                  "run_limit_exceeded": [
                    429
                  ],
                  "sandbox_ended": [
                    410
                  ],
                  "secret_missing": [
                    400
                  ],
                  "secrets_unavailable": [
                    503
                  ],
                  "session_required": [
                    403
                  ],
                  "source_file_not_found": [
                    400
                  ],
                  "source_file_too_large": [
                    413
                  ],
                  "source_rate_limited": [
                    503
                  ],
                  "source_ref_not_found": [
                    400
                  ],
                  "source_repository_not_accessible": [
                    404
                  ],
                  "source_repository_not_found": [
                    400
                  ],
                  "source_repository_not_private": [
                    400
                  ],
                  "source_repository_not_public": [
                    400
                  ],
                  "source_resolution_failed": [
                    502
                  ],
                  "source_resolution_timeout": [
                    504
                  ],
                  "spend_limit_exceeded": [
                    402
                  ],
                  "stale_membership": [
                    409
                  ],
                  "terminal_closed": [
                    410
                  ],
                  "terminal_observer_lost": [
                    410
                  ],
                  "timeout": [
                    504
                  ],
                  "unauthenticated": [
                    401
                  ],
                  "unavailable": [
                    503
                  ],
                  "unrecognised_word": [
                    400
                  ],
                  "unsupported_feature": [
                    422
                  ],
                  "volume_busy": [
                    409
                  ],
                  "volume_incompatible": [
                    409
                  ],
                  "volume_lease_lost": [
                    409
                  ],
                  "volume_not_attached": [
                    409
                  ],
                  "volume_restore_failed": [
                    502
                  ],
                  "volume_save_failed": [
                    409,
                    502
                  ],
                  "volume_unavailable": [
                    409
                  ],
                  "wrong_region": [
                    421
                  ]
                },
                "x-boxrouter-error-retry": {
                  "account_exists": "after_fix",
                  "account_unhealthy": "after_fix",
                  "actions_authority_changed": "after_fix",
                  "actions_candidate_ceiling_withdrawn": "after_fix",
                  "actions_candidate_outside_ceiling": "after_fix",
                  "actions_candidate_record_invalid": "after_fix",
                  "actions_create_budget_exhausted": "after_fix",
                  "actions_create_format_mismatch": "after_fix",
                  "actions_sandbox_protected": "never",
                  "agent_not_found": "after_fix",
                  "already_refunded": "never",
                  "authorization_error": "check_outcome",
                  "candidate_admission_unavailable": "never",
                  "capability_unavailable": "check_outcome",
                  "capability_unverified": "after_fix",
                  "card_setup_rate_limit": "safe",
                  "change_in_progress": "safe",
                  "code_ref_not_found": "after_fix",
                  "code_reference_moved": "after_fix",
                  "code_repository_not_authorized": "after_fix",
                  "code_repository_not_found": "after_fix",
                  "code_repository_not_private": "after_fix",
                  "code_repository_not_public": "after_fix",
                  "code_repository_resolution_failed": "safe",
                  "command_failed": "after_fix",
                  "command_observation_busy": "safe",
                  "conflict": "check_outcome",
                  "contract_violation": "check_outcome",
                  "credentials_rejected": "after_fix",
                  "database_unavailable": "check_outcome",
                  "directory_managed": "never",
                  "dispatch_limit_reached": "after_fix",
                  "dispute_open": "after_fix",
                  "dockerfile_context_unsupported": "after_fix",
                  "expired": "check_outcome",
                  "forbidden": "after_fix",
                  "fraud_review": "safe",
                  "gate_unavailable": "after_fix",
                  "idempotency_key_reused": "after_fix",
                  "identity_unavailable": "safe",
                  "image_architecture_unsupported": "after_fix",
                  "image_digest_resolution_failed": "after_fix",
                  "image_preparation_unsupported": "after_fix",
                  "image_setup_timeout": "after_fix",
                  "image_tag_unresolved": "after_fix",
                  "inline_secret_values_refused": "after_fix",
                  "insufficient_credit": "after_fix",
                  "internal_error": "never",
                  "invalid_manifest_encoding": "after_fix",
                  "invalid_observer_hop": "after_fix",
                  "invalid_request": "after_fix",
                  "invalid_run_spec": "after_fix",
                  "invalid_source_manifest": "after_fix",
                  "invalid_state": "check_outcome",
                  "job_claim_lost": "after_fix",
                  "knob_not_named": "after_fix",
                  "last_admin": "after_fix",
                  "launch_failed": "check_outcome",
                  "launch_incomplete": "check_outcome",
                  "launch_run_position_conflict": "after_fix",
                  "lifetime_cap_exceeded": "after_fix",
                  "lifetime_funding_conflict": "after_fix",
                  "lifetime_limit": "check_outcome",
                  "lifetime_used_up": "after_fix",
                  "managed_funding_unavailable": "safe",
                  "method_not_allowed": "after_fix",
                  "no_eligible_route": "after_fix",
                  "not_found": "check_outcome",
                  "not_named": "after_fix",
                  "not_running": "after_fix",
                  "nothing_to_refund": "never",
                  "organization_changed": "safe",
                  "output_limit": "check_outcome",
                  "overloaded": "safe",
                  "payment_declined": "after_fix",
                  "payment_method_required": "after_fix",
                  "payment_provider_rejected": "check_outcome",
                  "payment_provider_unavailable": "check_outcome",
                  "payments_unavailable": "safe",
                  "policy_denied": "after_fix",
                  "port_not_listening": "after_fix",
                  "preview_access_refused": "never",
                  "price_unknown": "after_fix",
                  "privacy_admission_unavailable": "after_fix",
                  "privacy_persistence_conflict": "after_fix",
                  "private_image_managed_route_unavailable": "after_fix",
                  "process_observer_lost": "check_outcome",
                  "promotion_already_redeemed": "never",
                  "promotion_code_invalid": "after_fix",
                  "provider_budget_exhausted": "never",
                  "provider_error": "check_outcome",
                  "provider_not_enabled": "after_fix",
                  "provider_policy_unknown": "after_fix",
                  "provider_quota": "after_fix",
                  "purchase_in_progress": "safe",
                  "quota_exceeded": "safe",
                  "quote_changed": "after_fix",
                  "rate_limited": "safe",
                  "recovery_sandbox_mismatch": "check_outcome",
                  "refund_amount_changed": "after_fix",
                  "refund_below_minimum": "never",
                  "refund_daily_limit": "safe",
                  "refund_fee_unavailable": "safe",
                  "refund_in_progress": "safe",
                  "refund_rate_limit": "safe",
                  "refund_retry_requires_support": "never",
                  "refund_window_closed": "never",
                  "repository_file_unsupported": "after_fix",
                  "repository_too_large": "after_fix",
                  "request_timeout": "safe",
                  "reserved_env_refused": "after_fix",
                  "resource_limit": "check_outcome",
                  "routing_overrides_forbidden": "after_fix",
                  "run_limit_exceeded": "after_fix",
                  "sandbox_ended": "check_outcome",
                  "secret_missing": "after_fix",
                  "secrets_unavailable": "never",
                  "session_required": "never",
                  "source_file_not_found": "after_fix",
                  "source_file_too_large": "after_fix",
                  "source_rate_limited": "safe",
                  "source_ref_not_found": "after_fix",
                  "source_repository_not_accessible": "after_fix",
                  "source_repository_not_found": "after_fix",
                  "source_repository_not_private": "after_fix",
                  "source_repository_not_public": "after_fix",
                  "source_resolution_failed": "safe",
                  "source_resolution_timeout": "safe",
                  "spend_limit_exceeded": "after_fix",
                  "stale_membership": "after_fix",
                  "terminal_closed": "after_fix",
                  "terminal_observer_lost": "after_fix",
                  "timeout": "check_outcome",
                  "unauthenticated": "after_fix",
                  "unavailable": "safe",
                  "unrecognised_word": "after_fix",
                  "unsupported_feature": "after_fix",
                  "volume_busy": "after_fix",
                  "volume_incompatible": "after_fix",
                  "volume_lease_lost": "after_fix",
                  "volume_not_attached": "after_fix",
                  "volume_restore_failed": "check_outcome",
                  "volume_save_failed": "check_outcome",
                  "volume_unavailable": "after_fix",
                  "wrong_region": "after_fix"
                }
              },
              "message": {
                "type": "string"
              },
              "details": {
                "type": "object",
                "description": "Code-specific context, spelled for programs. no_eligible_route carries considered,\nexcluded, closest and nearest; knob_not_named the knob and its values;\nunrecognised_word the path, the word and the known ones; not_named the gate, what\nthe call needed beyond the grant and the corrected requirements line; gate_unavailable\nthe gate and account; lifetime_limit the ceiling and this run. A creation that\nstopped before a sandbox existed may also carry `fallbacks_allowed`, `stopped_reason`\nand `attempts`, spelled and bounded as in the sandbox route selection.\ncapability_unavailable may identify the needed capability. A launch preparation failure can follow sandbox creation;\ninspect outcome and cleanup details before creating another. Clients must\npreserve fields they do not know.\n",
                "properties": {
                  "selection_version": {
                    "type": "integer",
                    "minimum": 0,
                    "description": "Current selected organization version for organization_changed."
                  },
                  "considered": {
                    "type": "integer",
                    "minimum": 0,
                    "description": "no_eligible_route only; how many routes were considered."
                  },
                  "excluded": {
                    "type": "array",
                    "description": "no_eligible_route only; every considered route that cannot serve the request. Each entry names its `provider` and the checks it failed (`failed` for a sandbox request, `reasons` and `exclusions` for a launch); clients must preserve fields they do not know.",
                    "items": {
                      "type": "object",
                      "required": [
                        "provider"
                      ],
                      "properties": {
                        "provider": {
                          "type": "string"
                        }
                      }
                    }
                  },
                  "closest": {
                    "type": [
                      "object",
                      "null"
                    ],
                    "description": "no_eligible_route only; the excluded route that fails fewest checks, or null."
                  },
                  "nearest": {
                    "type": "array",
                    "description": "no_eligible_route only; the smallest changes that would make a route eligible, nearest first. An entry names the change (`change` and `then_eligible` for a sandbox request, `provider`, `distance` and `failing` for a launch); clients must preserve fields they do not know.",
                    "items": {
                      "type": "object"
                    }
                  },
                  "requirement": {
                    "type": "string",
                    "description": "The SandboxProviderSpec family whose requirement would make this operation available."
                  },
                  "purchase_id": {
                    "type": "string",
                    "description": "Retained failed credit purchase ID, when a saved-card charge was declined."
                  },
                  "preview": {
                    "$ref": "#/components/schemas/CreditRefundPreview",
                    "description": "Current refund preview returned with 409 refund_amount_changed."
                  },
                  "quote": {
                    "$ref": "#/components/schemas/CreditPurchaseQuote",
                    "description": "Current purchase quote returned with 409 quote_changed."
                  },
                  "redemption": {
                    "$ref": "#/components/schemas/CreditPromotion",
                    "description": "Original promotion redemption returned with 409 promotion_already_redeemed."
                  },
                  "scope": {
                    "type": "string",
                    "enum": [
                      "workspace"
                    ],
                    "description": "spend_limit_exceeded only; which configured cap refused admission."
                  },
                  "period": {
                    "type": "string",
                    "enum": [
                      "total",
                      "daily",
                      "monthly"
                    ],
                    "description": "spend_limit_exceeded only; the cap period that applies."
                  },
                  "limit_nanodollars": {
                    "type": "integer",
                    "minimum": 1,
                    "description": "spend_limit_exceeded only; exact configured USD nanodollars."
                  },
                  "requested_nanodollars": {
                    "type": "integer",
                    "minimum": 1,
                    "description": "spend_limit_exceeded only; exact proposed managed hold."
                  },
                  "sign_in_method": {
                    "type": "string",
                    "description": "account_exists only: how the existing account with this verified address signs in (google, github, email or other)."
                  },
                  "masked_email": {
                    "type": "string",
                    "description": "account_exists only: that account's address, masked as `t…@gmail.com`."
                  },
                  "failure_reason": {
                    "type": "string",
                    "maxLength": 100,
                    "description": "Short safe card-decline reason; raw Stripe messages are not returned."
                  },
                  "names": {
                    "type": "array",
                    "uniqueItems": true,
                    "items": {
                      "$ref": "#/components/schemas/SecretName"
                    },
                    "description": "All manifest secret names that could not be resolved."
                  },
                  "fields": {
                    "type": "array",
                    "uniqueItems": true,
                    "items": {
                      "type": "string",
                      "enum": [
                        "preferences.order",
                        "preferences.sort",
                        "preferences.allow_fallbacks"
                      ]
                    },
                    "description": "routing_overrides_forbidden only; the prohibited request inputs."
                  },
                  "volume_id": {
                    "type": "string",
                    "description": "BoxRouter Volume ID involved in the error."
                  },
                  "writer_sandbox_id": {
                    "type": "string",
                    "description": "volume_busy only; the sandbox that holds the volume's writer lease, when it is a recorded sandbox."
                  },
                  "checkpoint": {
                    "type": "integer",
                    "minimum": 1,
                    "description": "Volume checkpoint involved in the error."
                  },
                  "limit_bytes": {
                    "type": "integer",
                    "minimum": 0
                  },
                  "observed_bytes": {
                    "type": "integer",
                    "minimum": 0
                  },
                  "mismatch": {
                    "type": "object",
                    "additionalProperties": false,
                    "required": [
                      "field",
                      "recorded",
                      "requested"
                    ],
                    "properties": {
                      "field": {
                        "type": "string",
                        "enum": [
                          "image",
                          "arch"
                        ]
                      },
                      "recorded": {
                        "type": "string"
                      },
                      "requested": {
                        "type": "string"
                      }
                    }
                  },
                  "volume_phase": {
                    "type": "string",
                    "enum": [
                      "check",
                      "branch",
                      "lease",
                      "identity",
                      "install",
                      "credential",
                      "mount",
                      "metadata",
                      "checkpoint",
                      "commit",
                      "write"
                    ]
                  },
                  "phase": {
                    "type": "string",
                    "enum": [
                      "code",
                      "setup",
                      "files",
                      "background",
                      "previews"
                    ],
                    "description": "Preparation phase that failed."
                  },
                  "command": {
                    "type": "string",
                    "description": "Command whose nonzero exit stopped launch preparation."
                  },
                  "exit_code": {
                    "type": "integer",
                    "description": "Exit code of the failed command, or of the process that exited before its port listened."
                  },
                  "stderr_tail": {
                    "type": "string",
                    "description": "At most the final 4 KiB of stderr from the failed command, with resolved secret values\nredacted. port_not_listening carries the same tail of the process's stderr.\n"
                  },
                  "stdout_tail": {
                    "type": "string",
                    "description": "port_not_listening only; at most the final 4 KiB of the process's stdout."
                  },
                  "agent": {
                    "type": "string",
                    "description": "Unknown catalog agent name."
                  },
                  "port": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 65535,
                    "description": "The sandbox port whose preview was refused (preview_access_refused) or that never accepted connections (port_not_listening)."
                  },
                  "revoked": {
                    "type": "boolean",
                    "description": "preview_access_refused only; true when the unwanted preview was ended and no\naccess to the port remains. False: it may still be reachable (outcome unknown).\n"
                  },
                  "preview_id": {
                    "type": "string",
                    "description": "preview_access_refused only; the identifier the provider gave the preview that may\nstill be reachable. Present only for a public preview.\n"
                  },
                  "url": {
                    "type": "string",
                    "format": "uri",
                    "description": "preview_access_refused only; the address of a public preview that may still be\nreachable. Never present for a private preview, whose address holds a credential,\nand never when it was ended.\n"
                  }
                }
              },
              "request_id": {
                "type": "string"
              },
              "doc_url": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "uri",
                "description": "Where the documentation explains this code: `https://boxrouter.ai/docs/error-codes#` followed by the code, for example `https://boxrouter.ai/docs/error-codes#no_eligible_route`. The page has one anchored row per code with what it means and what to do. BoxRouter sends it with every error; it is null for a code that has no documented row. Clients must accept an error body that omits it."
              },
              "fix": {
                "type": [
                  "string",
                  "null"
                ],
                "minLength": 1,
                "description": "Actionable change for the caller when the request cannot be completed. A refusal (4xx) always carries one; a server or provider fault, including an error event that ends a terminal or process stream, can answer null."
              },
              "operation_id": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Durable server operation ID for reconciliation after uncertain mutations."
              },
              "outcome": {
                "type": "string",
                "enum": [
                  "not_started",
                  "completed",
                  "partial",
                  "unknown"
                ],
                "description": "What is known about the requested side effect. `not_started` means nothing ran\nanywhere, at BoxRouter or at a provider; a launch-setup or process-start failure\nafter dispatch is `partial` or `unknown`. Unknown and partial forbid automatic\nreplay and always carry `retry: check_outcome`. An HTTP status alone does not establish\noutcome.\nMany refusals report not_started before the provider is asked anything. A read\n(GET or HEAD) has no side effect to be unsure about, so its failures report\nnot_started and carry the code's own retry value. A launch preparation failure\nhappens after the sandbox was created and setup commands may already have run, and\ndeleting the sandbox does not undo effects outside it: it reports partial once the\ncleanup is confirmed and unknown if it is not. A process that wait_for_port ended\nreports partial. volume_restore_failed on a resume or create,\nand volume_save_failed after the guest was read, report unknown or partial; they\ncarry the operation_id when the call was recorded, and their fix does not offer to\nsend the call again unchanged.\n"
              },
              "retry": {
                "type": "string",
                "enum": [
                  "safe",
                  "after_fix",
                  "check_outcome",
                  "never"
                ],
                "x-boxrouter-open-enum": true,
                "description": "What the caller may do next, fixed per code (x-boxrouter-error-retry): safe resends the\nsame request, after_fix changes the request or setup first, check_outcome reads\n`outcome` and the resource before resending, never does not resend. Branch on this\ninstead of the HTTP status.\n"
              },
              "retry_after_seconds": {
                "type": [
                  "integer",
                  "null"
                ],
                "minimum": 0,
                "description": "How long to wait before a `retry: safe` resend, as the Retry-After header says it; null when there is no wait to name."
              },
              "provider": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "native_code": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "The provider's machine-readable error code, unchanged, when it reports one."
              },
              "native_status": {
                "type": [
                  "integer",
                  "null"
                ],
                "description": "The provider's HTTP status, unchanged, when the failure came from a provider response."
              },
              "native_message": {
                "type": [
                  "string",
                  "null"
                ],
                "maxLength": 4096,
                "description": "The provider's own error message when it answered with an HTTP 4xx refusal (for example a plan limit); null otherwise. Capped at 512 characters, with whitespace collapsed. Credential secrets and token-shaped strings are removed before return. The literal `[redacted]` marker is used when all credential secret fields are at least 12 characters; legacy saved secrets shorter than 12 characters are removed without the marker."
              }
            }
          }
        }
      },
      "CreditRefundPreview": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "unused",
          "held_excluded",
          "fee",
          "principal",
          "tax",
          "total",
          "card"
        ],
        "properties": {
          "unused": {
            "type": "integer",
            "minimum": 0,
            "description": "Unused purchased credit in US cents, before held credit is excluded."
          },
          "held_excluded": {
            "type": "integer",
            "minimum": 0,
            "description": "Credit held for running sandboxes, in US cents."
          },
          "fee": {
            "type": "integer",
            "minimum": 0,
            "description": "Original Stripe processing fee retained, in US cents."
          },
          "principal": {
            "type": "integer",
            "minimum": 0,
            "description": "Tax-exclusive principal returned to the original card, in US cents."
          },
          "tax": {
            "type": "integer",
            "minimum": 0,
            "description": "Tax Stripe adds to the credit note, in US cents."
          },
          "total": {
            "type": "integer",
            "minimum": 0,
            "description": "Total Stripe will refund, in US cents."
          },
          "card": {
            "$ref": "#/components/schemas/MaskedCreditCard"
          }
        }
      },
      "MaskedCreditCard": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "brand": {
            "type": [
              "string",
              "null"
            ],
            "description": "Card brand; absent for Link methods."
          },
          "last4": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^[0-9]{4}$",
            "description": "Last four card digits; absent for Link methods."
          },
          "type": {
            "type": "string",
            "enum": [
              "card",
              "link"
            ],
            "x-boxrouter-open-enum": true
          },
          "email": {
            "type": "string",
            "format": "email",
            "description": "Link account email; present only when type is link."
          }
        },
        "allOf": [
          {
            "if": {
              "properties": {
                "type": {
                  "const": "link"
                }
              },
              "required": [
                "type"
              ]
            },
            "then": {
              "required": [
                "email"
              ],
              "properties": {
                "brand": {
                  "type": "null"
                },
                "last4": {
                  "type": "null"
                }
              }
            }
          },
          {
            "if": {
              "properties": {
                "type": {
                  "const": "card"
                }
              },
              "required": [
                "type"
              ]
            },
            "then": {
              "required": [
                "brand",
                "last4"
              ],
              "properties": {
                "brand": {
                  "type": "string"
                },
                "last4": {
                  "type": "string",
                  "pattern": "^[0-9]{4}$"
                }
              }
            }
          }
        ]
      },
      "CreditPurchaseQuote": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "amount",
          "tax",
          "total",
          "address_required"
        ],
        "properties": {
          "amount": {
            "type": "integer",
            "minimum": 1,
            "description": "Tax-exclusive credit amount in US cents; this is what is added to the balance."
          },
          "fee_minor": {
            "type": "integer",
            "minimum": 0,
            "description": "BoxRouter's purchase fee in US cents, computed by the server and charged on top of amount. Tax applies to amount plus fee. Absent on older services."
          },
          "tax": {
            "type": "integer",
            "minimum": 0,
            "description": "Estimated tax in US cents, on the credits and the fee."
          },
          "total": {
            "type": "integer",
            "minimum": 1,
            "description": "Estimated total to charge in US cents: amount plus fee_minor plus tax."
          },
          "address_required": {
            "type": "boolean"
          },
          "missing": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Required billing address fields missing for an exact tax quote."
          }
        }
      },
      "CreditPromotion": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "code",
          "amount_nanodollars",
          "description",
          "redeemed_at"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "The code in its canonical upper-case form."
          },
          "amount_nanodollars": {
            "type": "string",
            "maxLength": 19,
            "pattern": "^(?:[1-9][0-9]{0,17}|[1-8][0-9]{18}|9[0-1][0-9]{17}|92[0-1][0-9]{16}|922[0-2][0-9]{15}|9223[0-2][0-9]{14}|92233[0-6][0-9]{13}|922337[0-1][0-9]{12}|92233720[0-2][0-9]{10}|922337203[0-5][0-9]{9}|9223372036[0-7][0-9]{8}|92233720368[0-4][0-9]{7}|922337203685[0-3][0-9]{6}|9223372036854[0-6][0-9]{5}|92233720368547[0-6][0-9]{4}|922337203685477[0-4][0-9]{3}|9223372036854775[0-7][0-9]{2}|922337203685477580[0-7])$",
            "description": "Credit granted, in billionths of a US dollar, as a canonical positive signed 64-bit nanodollar string."
          },
          "description": {
            "type": "string",
            "description": "What the credit is for, as the promotion describes it."
          },
          "redeemed_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "AgentDetails": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "name",
          "display_name",
          "description",
          "manifest"
        ],
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 63,
            "pattern": "^[a-z][a-z0-9-]{0,62}$"
          },
          "display_name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128,
            "description": "The agent's human-facing name."
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "manifest": {
            "$ref": "#/components/schemas/AgentManifest"
          }
        }
      },
      "AgentManifest": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "name",
          "command"
        ],
        "description": "A reusable agent environment and command. A field this schema does not list is refused\nwith 400 before the launch is accepted. interactive defaults to true. When false, launch\nstarts the command unattended after preparation.\n",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 63,
            "pattern": "^[a-z][a-z0-9-]{0,62}$",
            "description": "A lowercase identifier for the agent."
          },
          "description": {
            "type": "string",
            "description": "Optional text describing the agent."
          },
          "image": {
            "oneOf": [
              {
                "type": "string",
                "minLength": 1,
                "description": "OCI image reference."
              },
              {
                "$ref": "#/components/schemas/DockerfileBuild"
              },
              {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "private_oci"
                ],
                "properties": {
                  "private_oci": {
                    "type": "string",
                    "minLength": 1,
                    "description": "OCI image reference in a registry that needs a login; send registry_credentials with the launch request."
                  }
                }
              }
            ],
            "description": "Omit to use the standard image. {private_oci} names an image whose registry needs a\nlogin, sent as `registry_credentials` on the launch request; it launches only on\nroutes that use your own provider keys, and not as an unattended run.\n"
          },
          "setup": {
            "type": "array",
            "items": {
              "type": "string",
              "pattern": "^[^\\u0000]*$"
            },
            "description": "Shell commands run in order before files and background commands."
          },
          "command": {
            "type": "string",
            "minLength": 1,
            "pattern": "^[^\\u0000]*$",
            "description": "Command to run in an attached terminal or as an unattended process after preparation succeeds."
          },
          "env": {
            "$ref": "#/components/schemas/LaunchEnvironment",
            "description": "Non-secret environment values applied to setup and the launch."
          },
          "secrets": {
            "type": "array",
            "uniqueItems": true,
            "items": {
              "$ref": "#/components/schemas/SecretName"
            },
            "description": "Names whose values are resolved by the server and added only to the create environment."
          },
          "required_env": {
            "$ref": "#/components/schemas/AgentRequiredEnvironment"
          },
          "max_copies": {
            "$ref": "#/components/schemas/AgentMaximumCopies"
          },
          "model_access": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ModelAccess"
            },
            "description": "Named secrets that configure this catalog agent for model access. A launch may select at most one."
          },
          "sign_in": {
            "type": "string",
            "minLength": 1,
            "maxLength": 256,
            "description": "What to do inside the agent when no recognized model secret is selected."
          },
          "files": {
            "type": "object",
            "propertyNames": {
              "pattern": "^(?:~/)?(?!/)(?!~/?$)(?!.*(?:^|/)\\.\\.(?:/|$))(?!.*(?:^|/)\\.(?:/|$))(?!.*\\/$)[^\\u0000]+$"
            },
            "additionalProperties": {
              "oneOf": [
                {
                  "type": "string"
                },
                {
                  "type": "object"
                }
              ]
            },
            "description": "Relative sandbox paths mapped to UTF-8 text or JSON objects, written before background commands."
          },
          "background": {
            "type": "array",
            "items": {
              "type": "string",
              "pattern": "^[^\\u0000]*$"
            },
            "description": "Shell commands started detached during preparation before the launch command starts."
          },
          "ports": {
            "type": "array",
            "uniqueItems": true,
            "items": {
              "type": "integer",
              "minimum": 1,
              "maximum": 65535
            },
            "description": "Ports to expose as previews. Naming ports adds the previews requirement to routing."
          },
          "interactive": {
            "type": "boolean",
            "default": true,
            "description": "When true, a client can attach a terminal; when false, launch starts the command unattended."
          },
          "preinstalled": {
            "type": "boolean",
            "default": false,
            "description": "Declares that the launch's image already carries this agent's harness. The catalog sets it for agents bundled in the agents image; the listAgents entry reports it."
          },
          "resources": {
            "$ref": "#/components/schemas/SandboxProviderSpecResources"
          },
          "lifetime_seconds": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1,
            "description": "Requested sandbox lifetime in seconds for this launch; the sandbox may run past its lifetime deadline. Null asks for a sandbox that never ends. Only a provider that never ends a sandbox serves it, and only on the workspace's own provider account. Left out, the create's own default applies: rolling credit reservations on a credit-funded route that can extend a lifetime, else 300 seconds."
          },
          "placement": {
            "$ref": "#/components/schemas/LaunchPlacement"
          },
          "code": {
            "$ref": "#/components/schemas/LaunchCode"
          },
          "source": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "repo",
              "ref",
              "path"
            ],
            "description": "For a launch, fetch this manifest file at the selected repository ref, then apply the other supplied manifest fields as overrides.",
            "properties": {
              "repo": {
                "type": "string",
                "minLength": 1
              },
              "ref": {
                "type": "string",
                "minLength": 1
              },
              "path": {
                "type": "string",
                "minLength": 1,
                "pattern": "^(?!/)(?!.*(?:^|/)\\.\\.(?:/|$))[^\\u0000]*$"
              }
            }
          },
          "volume": {
            "$ref": "#/components/schemas/AttachVolume",
            "description": "BoxRouter-managed volume reference and access mode attached to the created sandbox."
          }
        }
      },
      "DockerfileBuild": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "dockerfile"
        ],
        "properties": {
          "dockerfile": {
            "type": "string",
            "minLength": 1,
            "description": "Dockerfile source sent to the provider's builder; never executed on the BoxRouter host."
          },
          "context_artifact_id": {
            "type": "string",
            "minLength": 1,
            "description": "Workspace-owned tar build context. Reject paths escaping the context,\nspecial device files and unsafe links; enforce compressed and expanded\nsize limits before using it. Source file and directory builder helpers\npackage their inputs into this context rather than sending host paths.\n"
          }
        }
      },
      "LaunchEnvironment": {
        "type": "object",
        "propertyNames": {
          "pattern": "^[A-Za-z_][A-Za-z0-9_]*$"
        },
        "additionalProperties": {
          "type": "string",
          "pattern": "^[^\\u0000]*$"
        },
        "description": "Non-secret environment values applied to setup and the launch."
      },
      "SandboxProviderSpecResources": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "cpu_min": {
            "type": "number",
            "exclusiveMinimum": 0
          },
          "memory_min_mib": {
            "type": "integer",
            "minimum": 1
          },
          "disk_min_mib": {
            "type": "integer",
            "minimum": 1
          },
          "extendable_lifetime": {
            "type": "boolean",
            "const": true,
            "description": "Needed before POST /sandboxes/{sandbox_id}/lifetime may be called."
          },
          "region": {
            "type": "string",
            "minLength": 1,
            "description": "One value from the region registry: a provider's region (for example `provider:eu-west`),\nan area (EU) or a country (US). Never a list.\n"
          },
          "kernel": {
            "oneOf": [
              {
                "enum": [
                  "shared",
                  "filtered",
                  "dedicated"
                ]
              },
              {
                "type": "array",
                "minItems": 1,
                "uniqueItems": true,
                "items": {
                  "enum": [
                    "shared",
                    "filtered",
                    "dedicated"
                  ]
                }
              }
            ]
          },
          "paused_retention_seconds": {
            "type": "number",
            "exclusiveMinimum": 0
          },
          "arch": {
            "oneOf": [
              {
                "enum": [
                  "amd64",
                  "arm64"
                ]
              },
              {
                "type": "array",
                "minItems": 1,
                "uniqueItems": true,
                "items": {
                  "enum": [
                    "amd64",
                    "arm64"
                  ]
                }
              }
            ]
          },
          "run_seconds": {
            "type": "integer",
            "minimum": 1
          },
          "process_seconds": {
            "type": "integer",
            "minimum": 1
          }
        },
        "description": "Resource constraints, execution limits, and environment facts that must hold for this\nsandbox. The matcher compares each named value with declared resources and capabilities;\nfields left out impose no requirement.\n"
      },
      "LaunchPlacement": {
        "type": "object",
        "additionalProperties": false,
        "description": "Provider preferences for which routes to use and how to rank them, and the route pin that\na create takes as `route`. A route's `request_overrides` in the provider listing name\n`route` at the top level of a create; a launch takes it here, under `placement`.\n",
        "properties": {
          "preferences": {
            "$ref": "#/components/schemas/ProviderPreferences"
          },
          "route": {
            "$ref": "#/components/schemas/CreationRouteFilter"
          }
        }
      },
      "ProviderPreferences": {
        "type": "object",
        "additionalProperties": false,
        "description": "The one provider-preference contract shared by sandbox creation, launch placement and\nActions policy settings. Every property is optional; omitted properties inherit.\nPrecedence, narrowest last: workspace restrictions are the ceiling, then a repository\ndefault or named Actions policy, then a workflow, then request controls. Hard\nrestrictions (provider allowlists, route, account, supply, region, privacy, origin and\nspend) intersect and can only narrow; request ignore unions with workspace exclusions.\nA request true never lifts a workspace allow_fallbacks false. When workspace\nprevent_overrides is on, containing order, sort or allow_fallbacks is refused with\nrouting_overrides_forbidden even if the value matches the workspace; `only` still\nnarrows as a set and cannot reorder workspace ranking. Otherwise soft preference values\nreplace inherited values without widening authority. `order: []` and `ignore: []` are valid empty soft\narrays that name no preference and no exclusion; inherited hard authority is unchanged.\nEach list must hold distinct values; null is never valid for any property.\n`order` prioritizes named providers in listed order; eligible providers omitted from\nit remain candidates afterward, ranked by the existing router order. When `only`\nis supplied, it remains the hard ordered allowlist and caps eligible providers; `order`\nmay rearrange its members, while omitted members retain `only` order. `ignore`\nexcludes providers even when named by `only` or `order`. `sort` ranks routes\nwithin a provider. `allow_fallbacks` defaults to true and controls whether\ncreation may dispatch a later eligible route after a provider definitively refuses before\ncreating a sandbox. This includes another account for the same provider. False stops after\nthe first route dispatch. Eligibility and preparation may skip a route before dispatch.\nProvider, account, supply, payer and requirements constraints remain binding.\n",
        "properties": {
          "order": {
            "type": "array",
            "uniqueItems": true,
            "description": "Softly prioritize these providers in the listed order. Eligible providers omitted\nfrom this list remain candidates afterward using the existing router order. When\n`only` is supplied, it remains the ordered hard allowlist and caps eligibility;\nthis order rearranges its members and omitted members retain their `only` order.\n",
            "items": {
              "type": "string",
              "minLength": 1,
              "maxLength": 128,
              "pattern": "^[^\\u0000]*$"
            }
          },
          "only": {
            "$ref": "#/components/schemas/ProviderAllowlist"
          },
          "ignore": {
            "type": "array",
            "uniqueItems": true,
            "description": "Providers to exclude from routing, even if also named in `only` or `order`.",
            "items": {
              "type": "string",
              "minLength": 1,
              "maxLength": 128,
              "pattern": "^[^\\u0000]*$"
            }
          },
          "sort": {
            "type": "string",
            "enum": [
              "price",
              "time"
            ],
            "x-boxrouter-choices": {
              "price": {
                "label": "Price",
                "line": "Lowest hourly price first.",
                "measure": "price",
                "better": "lower"
              },
              "time": {
                "label": "Time",
                "line": "Shortest run time measured on reference workloads first.",
                "measure": "time",
                "better": "lower"
              }
            },
            "description": "How eligible routes are ranked. `price` picks the lowest hourly price. `time` picks the shortest run time, measured on reference workloads.\n"
          },
          "allow_fallbacks": {
            "type": "boolean",
            "default": true,
            "description": "Whether Cloud may dispatch a later eligible route after a provider definitively\nrefuses before creating a sandbox; defaults to true and continues until a route\ncreates the sandbox or no eligible route remains. If `only` is supplied, it\nlimits eligible providers; `preferences.order` takes precedence for their order, with\n`preferences.sort` ranking routes within each provider.\nFalse stops after the first route dispatch, including when a later route uses another\naccount for the same provider. Local eligibility or preparation failures may skip a\nroute before dispatch. This does not expand the provider allowlist or relax route,\naccount, supply, payer or requirements restrictions.\n"
          }
        }
      },
      "ProviderAllowlist": {
        "type": "array",
        "minItems": 1,
        "uniqueItems": true,
        "description": "Used as `preferences.only`, this is the hard allowlist of eligible providers. `preferences.order`\ntakes precedence for their order; otherwise this list's order applies. `preferences.sort`\nranks eligible routes within each provider. Route, account, supply,\npayer and requirements restrictions still constrain every route, and unlisted providers\nare never considered. A one-provider list prevents cross-provider fallback while allowing\nlater eligible routes for that provider when `preferences.allow_fallbacks` is true.\nSetting it to false stops after the first route dispatch, including a later account for\nthe same provider.\n",
        "items": {
          "type": "string",
          "minLength": 1,
          "maxLength": 128,
          "pattern": "^[^\\u0000]*$"
        }
      },
      "CreationRouteFilter": {
        "type": "object",
        "additionalProperties": false,
        "description": "The remaining route filters. Each singular value is a hard pin: `id` and `account_id` name\nexactly one route or connected account and `supply` one funding authority. Fallback never\nmoves a pin, a volume remains attached to its selected route, and these\nfilters only narrow workspace restrictions.\n",
        "properties": {
          "id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128,
            "pattern": "^[^\\u0000]*$"
          },
          "account_id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128,
            "pattern": "^[^\\u0000]*$",
            "description": "Connected account ID. A provider disabled on this deployment returns 409 provider_not_enabled before routing."
          },
          "supply": {
            "type": "string",
            "enum": [
              "byok",
              "managed"
            ]
          }
        }
      },
      "LaunchCode": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "repo",
          "ref"
        ],
        "description": "Clone a GitHub repository at the requested ref before setup.",
        "properties": {
          "repo": {
            "type": "string",
            "minLength": 1,
            "pattern": "^(?:https://github\\.com/)?[A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+(?:\\.git)?$"
          },
          "ref": {
            "type": "string",
            "minLength": 1
          },
          "directory": {
            "type": "string",
            "minLength": 1,
            "pattern": "^(?!/)(?!.*(?:^|/)\\.\\.(?:/|$))[^\\u0000]*$",
            "description": "Relative directory in the checked-out repository."
          }
        }
      },
      "AttachVolume": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id"
        ],
        "properties": {
          "id": {
            "$ref": "#/components/schemas/VolumeId"
          },
          "path": {
            "type": "string",
            "pattern": "^/[^\\u0000]*$",
            "default": "/workspace",
            "description": "Absolute folder the checkpoint is restored into, replacing what the image has there. Repeated\nseparators and `.` path components are normalized; any `..` component is rejected. The path\nmust not be `/`, under /proc, /sys, /dev, /etc, /usr, /bin, /sbin, /lib or /run, or equal to\nor an ancestor of the internal `/tmp/boxrouter-volume` scratch path.\n"
          },
          "checkpoint": {
            "type": "integer",
            "minimum": 1,
            "description": "Checkpoint to restore; omitted means the head. An empty volume restores nothing. A\ncheckpoint saved from a branch sandbox is not the head and can be selected by number with\nwrite, branch or read access; read mounts exactly that checkpoint's files, never the head.\n"
          },
          "access": {
            "type": "string",
            "enum": [
              "write",
              "read",
              "shared",
              "branch"
            ],
            "default": "write",
            "description": "The access mode requested for this sandbox. Omitted means write. Launch modes are write,\nread, shared, and branch. Checkpoints and branches remain capability-gated.\n"
          }
        }
      },
      "VolumeId": {
        "type": "string",
        "pattern": "^vol_[0-9a-f]{32}$",
        "description": "BoxRouter-managed Volume ID. Provider-native volume requirements are not accepted."
      },
      "AgentNotFoundErrorResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/ApiErrorResponse"
          },
          {
            "type": "object",
            "properties": {
              "error": {
                "type": "object",
                "required": [
                  "code"
                ],
                "properties": {
                  "code": {
                    "type": "string",
                    "const": "agent_not_found"
                  },
                  "details": {
                    "type": "object",
                    "properties": {
                      "agent": {
                        "type": "string",
                        "minLength": 1
                      }
                    }
                  }
                }
              }
            }
          }
        ]
      },
      "LaunchRequest": {
        "type": "object",
        "unevaluatedProperties": false,
        "allOf": [
          {
            "$ref": "#/components/schemas/LaunchRequestFields"
          }
        ]
      },
      "LaunchRequestFields": {
        "type": "object",
        "description": "Exactly one of a catalog agent name or an inline manifest is required.",
        "properties": {
          "privacy": {
            "$ref": "#/components/schemas/PrivacyPolicy",
            "description": "Privacy floors for the sandbox created by this launch. Cloud carries this policy unchanged into deferred sandbox materialization."
          },
          "agent": {
            "type": "string",
            "minLength": 1,
            "maxLength": 63,
            "pattern": "^[a-z][a-z0-9-]{0,62}$"
          },
          "manifest": {
            "$ref": "#/components/schemas/LaunchManifest"
          },
          "overrides": {
            "$ref": "#/components/schemas/LaunchOverrides"
          },
          "additional_secret_refs": {
            "$ref": "#/components/schemas/AdditionalSecretReferences"
          },
          "credential_delivery": {
            "$ref": "#/components/schemas/CredentialDeliveryPolicy",
            "description": "Whether compatible environment fallback is allowed or protected delivery is required."
          },
          "run": {
            "$ref": "#/components/schemas/LaunchRun",
            "description": "Optional client supplied batch metadata. Each launch remains independent; the server stores the values on its launch operation, labels the sandbox group and copy, and echoes this object in the successful Launch result. The server does not check group completeness."
          },
          "registry_credentials": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "username",
              "password"
            ],
            "properties": {
              "username": {
                "type": "string",
                "minLength": 1,
                "pattern": "^[^\\u0000]*$"
              },
              "password": {
                "type": "string",
                "minLength": 1,
                "writeOnly": true,
                "pattern": "^[^\\u0000]*$"
              }
            },
            "description": "Request-only login for a manifest whose image is {private_oci}; required with it and\nrefused without it. Both strings are non-empty, at most 64 KiB UTF-8 bytes together.\nIt is passed to the provider to set up a copy of the image and is never stored,\nlogged, traced or returned. Not accepted by unattended launch runs.\n"
          },
          "secret_values": {
            "type": "object",
            "propertyNames": {
              "$ref": "#/components/schemas/SecretName"
            },
            "additionalProperties": {
              "type": "string",
              "writeOnly": true,
              "maxLength": 16384,
              "pattern": "^[^\\u0000]*$"
            },
            "description": "Request-only secret values for names declared by the resolved manifest. Unknown\nnames are invalid_request. The server enforces request size limits outside JSON\nSchema validation. Values are never stored, returned or logged.\n"
          }
        },
        "oneOf": [
          {
            "required": [
              "agent"
            ]
          },
          {
            "required": [
              "manifest"
            ]
          }
        ]
      },
      "PrivacyPolicy": {
        "type": "object",
        "additionalProperties": false,
        "description": "Optional privacy requirements for a sandbox request. Omitted values inherit the\nworkspace and customer-key floors; omission never resets them. Supplied values may\nonly tighten those floors. `data_collection: deny` requires both no model training\nand zero provider data retention; a route that retains logs does not satisfy deny,\neven when `zdr` is false. `zdr: true` independently requires zero retention and is\nnot a training-policy predicate. Neither setting consents to BoxRouter capture or\npromises that an eligible provider or end-to-end zero-retention route exists.\n`boxrouter_content_retention` separately restricts BoxRouter sandbox-content\nhandling. Transient wins over ordinary across workspace, key, request and immutable\norigin floors; an ordinary request cannot relax an inherited transient floor.\nUnsupported transient operations and unqualified routes are refused. Omission\npreserves inheritance and the legacy combined meaning of request `zdr: true`;\nexplicitly choosing ordinary separates BoxRouter retention from provider ZDR.\n",
        "properties": {
          "data_collection": {
            "type": "string",
            "enum": [
              "allow",
              "deny"
            ],
            "description": "Require the route to allow or deny provider data collection."
          },
          "zdr": {
            "type": "boolean",
            "description": "Require zero provider data retention when true."
          },
          "boxrouter_content_retention": {
            "type": "string",
            "enum": [
              "ordinary",
              "transient"
            ],
            "description": "Ordinary allows normal bounded service retention; transient requires the\nsupported non-persistent sandbox-content profile. This is not provider\nqualification, permission to train, or consent to capture additional content.\n"
          }
        }
      },
      "LaunchManifest": {
        "anyOf": [
          {
            "$ref": "#/components/schemas/AgentManifest"
          },
          {
            "$ref": "#/components/schemas/LaunchSourceManifest"
          }
        ],
        "description": "A complete inline agent manifest or a source wrapper whose command can come from the referenced file."
      },
      "LaunchSourceManifest": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "name",
          "source"
        ],
        "description": "Request wrapper that loads the base agent manifest from source. command may be omitted to use the command in that file; supplied fields override the loaded manifest.",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 63,
            "pattern": "^[a-z][a-z0-9-]{0,62}$",
            "description": "A lowercase identifier for the agent."
          },
          "description": {
            "type": "string",
            "description": "Optional text describing the agent."
          },
          "image": {
            "oneOf": [
              {
                "type": "string",
                "minLength": 1,
                "description": "OCI image reference."
              },
              {
                "$ref": "#/components/schemas/DockerfileBuild"
              },
              {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "private_oci"
                ],
                "properties": {
                  "private_oci": {
                    "type": "string",
                    "minLength": 1,
                    "description": "OCI image reference in a registry that needs a login; send registry_credentials with the launch request."
                  }
                }
              }
            ],
            "description": "Omit to use the standard image. {private_oci} names an image whose registry needs a\nlogin, sent as `registry_credentials` on the launch request; it launches only on\nroutes that use your own provider keys, and not as an unattended run.\n"
          },
          "setup": {
            "type": "array",
            "items": {
              "type": "string",
              "pattern": "^[^\\u0000]*$"
            },
            "description": "Shell commands run in order before files and background commands."
          },
          "command": {
            "type": "string",
            "minLength": 1,
            "pattern": "^[^\\u0000]*$",
            "description": "Command to run in an attached terminal or as an unattended process after preparation succeeds."
          },
          "env": {
            "$ref": "#/components/schemas/LaunchEnvironment",
            "description": "Non-secret environment values applied to setup and the launch."
          },
          "secrets": {
            "type": "array",
            "uniqueItems": true,
            "items": {
              "$ref": "#/components/schemas/SecretName"
            },
            "description": "Names whose values are resolved by the server and added only to the create environment."
          },
          "required_env": {
            "$ref": "#/components/schemas/AgentRequiredEnvironment"
          },
          "max_copies": {
            "$ref": "#/components/schemas/AgentMaximumCopies"
          },
          "model_access": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ModelAccess"
            },
            "description": "Named secrets that configure this catalog agent for model access. A launch may select at most one."
          },
          "sign_in": {
            "type": "string",
            "minLength": 1,
            "maxLength": 256,
            "description": "What to do inside the agent when no recognized model secret is selected."
          },
          "files": {
            "type": "object",
            "propertyNames": {
              "pattern": "^(?:~/)?(?!/)(?!~/?$)(?!.*(?:^|/)\\.\\.(?:/|$))(?!.*(?:^|/)\\.(?:/|$))(?!.*\\/$)[^\\u0000]+$"
            },
            "additionalProperties": {
              "oneOf": [
                {
                  "type": "string"
                },
                {
                  "type": "object"
                }
              ]
            },
            "description": "Relative sandbox paths mapped to UTF-8 text or JSON objects, written before background commands."
          },
          "background": {
            "type": "array",
            "items": {
              "type": "string",
              "pattern": "^[^\\u0000]*$"
            },
            "description": "Shell commands started detached during preparation before the launch command starts."
          },
          "ports": {
            "type": "array",
            "uniqueItems": true,
            "items": {
              "type": "integer",
              "minimum": 1,
              "maximum": 65535
            },
            "description": "Ports to expose as previews. Naming ports adds the previews requirement to routing."
          },
          "interactive": {
            "type": "boolean",
            "default": true,
            "description": "When true, a client can attach a terminal; when false, launch starts the command unattended."
          },
          "preinstalled": {
            "type": "boolean",
            "default": false,
            "description": "Declares that the launch's image already carries this agent's harness. The catalog sets it for agents bundled in the agents image; the listAgents entry reports it."
          },
          "resources": {
            "$ref": "#/components/schemas/SandboxProviderSpecResources"
          },
          "lifetime_seconds": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1,
            "description": "Requested sandbox lifetime in seconds for this launch; the sandbox may run past its lifetime deadline. Null asks for a sandbox that never ends. Only a provider that never ends a sandbox serves it, and only on the workspace's own provider account. Left out, the create's own default applies: rolling credit reservations on a credit-funded route that can extend a lifetime, else 300 seconds."
          },
          "placement": {
            "$ref": "#/components/schemas/LaunchPlacement"
          },
          "code": {
            "$ref": "#/components/schemas/LaunchCode"
          },
          "source": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "repo",
              "ref",
              "path"
            ],
            "description": "For a launch, fetch this manifest file at the selected repository ref, then apply the other supplied manifest fields as overrides.",
            "properties": {
              "repo": {
                "type": "string",
                "minLength": 1
              },
              "ref": {
                "type": "string",
                "minLength": 1
              },
              "path": {
                "type": "string",
                "minLength": 1,
                "pattern": "^(?!/)(?!.*(?:^|/)\\.\\.(?:/|$))[^\\u0000]*$"
              }
            }
          },
          "volume": {
            "$ref": "#/components/schemas/AttachVolume",
            "description": "BoxRouter-managed volume reference and access mode attached to the created sandbox."
          }
        }
      },
      "LaunchOverrides": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "image": {
            "oneOf": [
              {
                "type": "string",
                "minLength": 1,
                "description": "OCI image reference."
              },
              {
                "$ref": "#/components/schemas/DockerfileBuild"
              }
            ]
          },
          "resources": {
            "$ref": "#/components/schemas/SandboxProviderSpecResources"
          },
          "lifetime_seconds": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1,
            "description": "Requested sandbox lifetime in seconds, replacing the manifest value. The sandbox may run past its lifetime deadline. Null asks for a sandbox with no lifetime: it runs until destroyed, and only a provider that never ends a sandbox serves it, on the workspace's own provider account. If a chosen number exceeds every otherwise matching account's cap, launch fails with `lifetime_cap_exceeded`; the requested value is not lowered."
          },
          "code": {
            "$ref": "#/components/schemas/LaunchCode",
            "description": "Repository/ref to check out, overriding the manifest's code source."
          },
          "placement": {
            "$ref": "#/components/schemas/LaunchPlacement"
          },
          "env": {
            "$ref": "#/components/schemas/LaunchEnvironment"
          }
        }
      },
      "AdditionalSecretReferences": {
        "type": "object",
        "propertyNames": {
          "pattern": "^[A-Za-z_][A-Za-z0-9_]*$"
        },
        "additionalProperties": {
          "$ref": "#/components/schemas/SecretReference"
        }
      },
      "SecretReference": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "secret_name"
        ],
        "properties": {
          "secret_name": {
            "$ref": "#/components/schemas/SecretName"
          }
        }
      },
      "CredentialDeliveryPolicy": {
        "type": "string",
        "enum": [
          "prefer_native",
          "require_native"
        ],
        "default": "prefer_native"
      },
      "LaunchRun": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "index",
          "count"
        ],
        "description": "Client supplied identity and position for one independently managed launch.",
        "properties": {
          "id": {
            "type": "string",
            "minLength": 22,
            "maxLength": 128,
            "description": "Random group identifier chosen by the client with at least 128 bits of entropy."
          },
          "index": {
            "type": "integer",
            "minimum": 0,
            "description": "Zero-based position of this launch; must be less than count."
          },
          "count": {
            "type": "integer",
            "minimum": 1,
            "description": "Number of launches the client intends to submit; completeness is not checked."
          }
        }
      },
      "LaunchOperation": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "agent",
          "repo",
          "sha",
          "status",
          "current_phase",
          "phases",
          "result",
          "error",
          "failure_status",
          "created_at",
          "updated_at"
        ],
        "description": "Durable, workspace-owned launch work. Poll while queued or running. A succeeded\noperation contains its final Launch in result; a failed operation contains the\noriginal structured error, with the HTTP status recorded in failure_status.\nSecret values are never stored or returned.\n",
        "allOf": [
          {
            "if": {
              "properties": {
                "status": {
                  "const": "succeeded"
                }
              },
              "required": [
                "status"
              ]
            },
            "then": {
              "properties": {
                "result": {
                  "$ref": "#/components/schemas/Launch"
                },
                "error": {
                  "type": "null"
                },
                "failure_status": {
                  "type": "null"
                }
              }
            }
          },
          {
            "if": {
              "properties": {
                "status": {
                  "const": "failed"
                }
              },
              "required": [
                "status"
              ]
            },
            "then": {
              "properties": {
                "result": {
                  "type": "null"
                },
                "error": {
                  "$ref": "#/components/schemas/LaunchOperationError"
                },
                "failure_status": {
                  "type": "integer",
                  "minimum": 400,
                  "maximum": 599
                }
              }
            }
          }
        ],
        "properties": {
          "id": {
            "type": "string",
            "minLength": 1
          },
          "agent": {
            "type": "string",
            "minLength": 1
          },
          "repo": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "description": "Canonical resolved code repository, or null when the launch has no code checkout."
          },
          "sha": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^[0-9a-f]{40}$",
            "description": "Immutable commit selected for the code checkout, or null when no code is requested."
          },
          "status": {
            "type": "string",
            "enum": [
              "queued",
              "running",
              "succeeded",
              "failed"
            ]
          },
          "current_phase": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "preparing_image",
              "create",
              "code",
              "setup",
              "files",
              "background",
              "previews",
              null
            ]
          },
          "phases": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/LaunchOperationPhase"
            }
          },
          "result": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/Launch"
              },
              {
                "type": "null"
              }
            ]
          },
          "error": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/LaunchOperationError"
              },
              {
                "type": "null"
              }
            ]
          },
          "failure_status": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 400,
            "maximum": 599
          },
          "sandbox_id": {
            "type": "string",
            "minLength": 1
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "Launch": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "sandbox_id",
          "agent",
          "phases",
          "previews",
          "expires_at",
          "effective_lifetime_seconds",
          "reused"
        ],
        "description": "Result of one launch. id and sandbox_id are the same BoxRouter-owned sandbox ID.\nThe stored result of a launch. A matching idempotent retry returns this result unchanged.\n",
        "properties": {
          "interactive": {
            "type": "boolean",
            "description": "Whether the resolved manifest uses a terminal, after source manifests and overrides. False means launch preparation started the unattended command. Older servers may omit this field."
          },
          "id": {
            "type": "string",
            "minLength": 1
          },
          "sandbox_id": {
            "type": "string",
            "minLength": 1
          },
          "agent": {
            "type": "string",
            "minLength": 1,
            "description": "Name of the resolved catalog or inline manifest."
          },
          "phases": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/LaunchPhase"
            }
          },
          "previews": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/LaunchPreview"
            }
          },
          "expires_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "The sandbox's lifetime deadline; null when it was created with no lifetime."
          },
          "effective_lifetime_seconds": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1,
            "description": "Sandbox lifetime selected for this successful launch, in seconds: the lifetime the launch asked for, or the one the route armed when the manifest left it out (a rolling credit reservation window or the create's 300-second default). Null when the sandbox was created with no lifetime."
          },
          "reused": {
            "type": "boolean",
            "description": "Value recorded with the original launch result; it does not indicate whether the current create request is a replay."
          },
          "credential_delivery": {
            "$ref": "#/components/schemas/CredentialDelivery",
            "description": "Safe per-destination delivery mode and hosts; values and credential IDs are never returned. Omitted when the request has no typed selections or saved secret references."
          },
          "run": {
            "$ref": "#/components/schemas/LaunchRun",
            "description": "The run metadata supplied with this launch, echoed unchanged when present."
          }
        }
      },
      "LaunchPhase": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "name",
          "status",
          "seconds"
        ],
        "properties": {
          "name": {
            "type": "string",
            "enum": [
              "source",
              "preparing_image",
              "create",
              "code",
              "setup",
              "files",
              "background",
              "previews"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "completed"
            ]
          },
          "seconds": {
            "type": "number",
            "minimum": 0
          },
          "command": {
            "type": "string",
            "description": "The command run in this phase, when the phase executes a command. For the\nsource phase, this is the resolved manifest command the client should open\nin the interactive terminal.\n"
          },
          "repo": {
            "type": "string",
            "minLength": 1,
            "description": "Source repository resolved for a source phase."
          },
          "sha": {
            "type": "string",
            "pattern": "^[0-9a-f]{40}$",
            "description": "Immutable source commit resolved for a source phase."
          },
          "exit_code": {
            "type": "integer",
            "description": "Command exit status, when the phase executes a command."
          }
        }
      },
      "LaunchPreview": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "port",
          "url"
        ],
        "properties": {
          "port": {
            "type": "integer",
            "minimum": 1,
            "maximum": 65535
          },
          "url": {
            "type": "string",
            "format": "uri"
          }
        }
      },
      "CredentialDelivery": {
        "type": "object",
        "minProperties": 1,
        "propertyNames": {
          "pattern": "^[A-Za-z_][A-Za-z0-9_]*$"
        },
        "additionalProperties": {
          "$ref": "#/components/schemas/CredentialDeliveryEntry"
        }
      },
      "CredentialDeliveryEntry": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "mode",
          "hosts"
        ],
        "properties": {
          "mode": {
            "type": "string",
            "enum": [
              "provider_protected",
              "environment"
            ]
          },
          "hosts": {
            "type": "array",
            "uniqueItems": true,
            "items": {
              "$ref": "#/components/schemas/SandboxProviderSpecHostname"
            }
          }
        },
        "allOf": [
          {
            "if": {
              "properties": {
                "mode": {
                  "const": "provider_protected"
                }
              },
              "required": [
                "mode"
              ]
            },
            "then": {
              "properties": {
                "hosts": {
                  "minItems": 1
                }
              }
            }
          },
          {
            "if": {
              "properties": {
                "mode": {
                  "const": "environment"
                }
              },
              "required": [
                "mode"
              ]
            },
            "then": {
              "properties": {
                "hosts": {
                  "maxItems": 0
                }
              }
            }
          }
        ]
      },
      "SandboxProviderSpecHostname": {
        "type": "string",
        "oneOf": [
          {
            "pattern": "^(?=.{1,253}(?![\\s\\S]))(?![0-9.]+(?![\\s\\S]))[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?(?:\\.[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?)*(?![\\s\\S])"
          },
          {
            "pattern": "^(?=.{3,255}(?![\\s\\S]))\\*\\.(?![0-9.]+(?![\\s\\S]))[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?(?:\\.[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?)*(?![\\s\\S])"
          }
        ]
      },
      "LaunchOperationError": {
        "type": "object",
        "required": [
          "error"
        ],
        "description": "Structured error retained by asynchronous execution. It has no request_id when the\nfailure occurs after the launch request has returned 202; clients can correlate the\nfailure by the operation id instead.\n",
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "code",
              "message",
              "outcome"
            ],
            "properties": {
              "code": {
                "type": "string"
              },
              "message": {
                "type": "string"
              },
              "request_id": {
                "type": "string",
                "description": "Present only when the failure originated in the initial HTTP request."
              },
              "fix": {
                "type": "string"
              },
              "details": {
                "type": "object",
                "description": "Structured error context; shape depends on code.",
                "properties": {
                  "phase": {
                    "type": "string",
                    "enum": [
                      "code",
                      "setup",
                      "files",
                      "background",
                      "previews"
                    ]
                  },
                  "command": {
                    "type": "string",
                    "description": "Present with exit_code and stderr_tail when a command failed."
                  },
                  "exit_code": {
                    "type": "integer",
                    "description": "Present with command and stderr_tail when a command failed."
                  },
                  "stderr_tail": {
                    "type": "string",
                    "description": "At most the final 4 KiB of stderr when a command failed; resolved secret values are redacted."
                  }
                },
                "dependentRequired": {
                  "command": [
                    "exit_code",
                    "stderr_tail"
                  ],
                  "exit_code": [
                    "command",
                    "stderr_tail"
                  ],
                  "stderr_tail": [
                    "command",
                    "exit_code"
                  ]
                }
              },
              "outcome": {
                "type": "string",
                "enum": [
                  "not_started",
                  "completed",
                  "partial",
                  "unknown"
                ]
              }
            }
          }
        }
      },
      "LaunchOperationPhase": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "name",
          "status",
          "seconds"
        ],
        "properties": {
          "name": {
            "type": "string",
            "enum": [
              "preparing_image",
              "create",
              "code",
              "setup",
              "files",
              "background",
              "previews"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "running",
              "completed",
              "failed"
            ]
          },
          "seconds": {
            "type": [
              "number",
              "null"
            ],
            "minimum": 0,
            "description": "Elapsed phase time in seconds; null while the phase is running."
          },
          "command": {
            "type": "string",
            "description": "The command run in this phase, when the phase executes a command."
          },
          "exit_code": {
            "type": "integer",
            "description": "Command exit status, when the phase executes a command."
          }
        }
      },
      "LaunchInputErrorResponse": {
        "oneOf": [
          {
            "$ref": "#/components/schemas/InvalidRequestErrorResponse"
          },
          {
            "$ref": "#/components/schemas/SecretMissingErrorResponse"
          }
        ]
      },
      "InvalidRequestErrorResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/ApiErrorResponse"
          },
          {
            "type": "object",
            "properties": {
              "error": {
                "type": "object",
                "required": [
                  "code"
                ],
                "properties": {
                  "code": {
                    "type": "string",
                    "const": "invalid_request"
                  }
                }
              }
            }
          }
        ]
      },
      "SecretMissingErrorResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/ApiErrorResponse"
          },
          {
            "type": "object",
            "properties": {
              "error": {
                "type": "object",
                "required": [
                  "code",
                  "details"
                ],
                "properties": {
                  "code": {
                    "type": "string",
                    "const": "secret_missing"
                  },
                  "details": {
                    "type": "object",
                    "required": [
                      "names"
                    ],
                    "properties": {
                      "names": {
                        "type": "array",
                        "minItems": 1,
                        "uniqueItems": true,
                        "items": {
                          "$ref": "#/components/schemas/SecretName"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        ]
      },
      "LaunchConflictErrorResponse": {
        "oneOf": [
          {
            "$ref": "#/components/schemas/NoEligibleRouteErrorResponse"
          },
          {
            "$ref": "#/components/schemas/IdempotencyConflictErrorResponse"
          },
          {
            "$ref": "#/components/schemas/CopiesUnavailableErrorResponse"
          }
        ]
      },
      "NoEligibleRouteErrorResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/ApiErrorResponse"
          },
          {
            "type": "object",
            "properties": {
              "error": {
                "type": "object",
                "required": [
                  "code",
                  "fix",
                  "details"
                ],
                "properties": {
                  "code": {
                    "type": "string",
                    "const": "no_eligible_route"
                  },
                  "fix": {
                    "type": "string",
                    "minLength": 1,
                    "description": "The smallest change that would fit. On a command to an existing sandbox whose\ncreating API key has been revoked, the sandbox keeps that key's privacy settings\nfor its whole life and no other key may run commands in it: the response is this\n409 with a failed reason of creator_key_revoked and a fix that says to create a\nnew sandbox with a current key. Nothing was dispatched, and deleting the sandbox\nstill works with any key in the workspace.\n"
                  },
                  "details": {
                    "type": "object",
                    "required": [
                      "excluded"
                    ],
                    "properties": {
                      "excluded": {
                        "type": "array",
                        "items": {
                          "$ref": "#/components/schemas/RouteExclusion"
                        }
                      },
                      "nearest": {
                        "type": "array",
                        "items": {
                          "$ref": "#/components/schemas/Relaxation"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        ]
      },
      "RouteExclusion": {
        "type": "object",
        "required": [
          "provider",
          "reasons",
          "exclusions"
        ],
        "description": "One route that cannot serve the request, with SandboxProviderSpec reasons.",
        "properties": {
          "provider": {
            "type": "string"
          },
          "reasons": {
            "type": "array",
            "uniqueItems": true,
            "items": {
              "type": "string"
            },
            "description": "SandboxProviderSpec match codes such as property_mismatch, capability_unsupported, prerequisite_missing or capacity_unavailable."
          },
          "exclusions": {
            "type": "array",
            "description": "Each failing check, as the matcher reports it. Known fields are capability (the\nfamily), profile, property, requested, offered, rule, reason, explanation, upstream\nand evidence (source identifiers); clients must preserve fields they do not know.\n",
            "items": {
              "type": "object",
              "properties": {
                "capability": {
                  "type": "string"
                },
                "profile": {
                  "type": "string"
                },
                "property": {
                  "type": "string"
                },
                "rule": {
                  "type": "string"
                },
                "reason": {
                  "type": "string"
                },
                "explanation": {
                  "type": "string"
                },
                "evidence": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              }
            }
          }
        }
      },
      "Relaxation": {
        "type": "object",
        "required": [
          "provider",
          "distance",
          "failing"
        ],
        "description": "A route that would become eligible if the failing requirements were relaxed, nearest\nfirst. A suggestion only; nothing is relaxed automatically.\n",
        "properties": {
          "provider": {
            "type": "string"
          },
          "distance": {
            "type": "integer",
            "minimum": 1,
            "description": "Number of distinct failing (family, property) pairs."
          },
          "failing": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "offered_by"
              ],
              "properties": {
                "capability": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "property": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "offered_by": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  },
                  "description": "Other considered providers that offer the requested value."
                }
              }
            }
          }
        }
      },
      "IdempotencyConflictErrorResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/ApiErrorResponse"
          },
          {
            "type": "object",
            "properties": {
              "error": {
                "type": "object",
                "required": [
                  "code",
                  "fix"
                ],
                "properties": {
                  "code": {
                    "type": "string",
                    "const": "conflict"
                  },
                  "fix": {
                    "type": "string",
                    "minLength": 1,
                    "description": "Use a new idempotency key for a request with different input."
                  },
                  "outcome": {
                    "type": "string",
                    "const": "not_started"
                  }
                }
              }
            }
          }
        ]
      },
      "CopiesUnavailableErrorResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/ApiErrorResponse"
          },
          {
            "type": "object",
            "properties": {
              "error": {
                "type": "object",
                "required": [
                  "code",
                  "fix"
                ],
                "properties": {
                  "code": {
                    "type": "string",
                    "const": "capability_unavailable"
                  },
                  "fix": {
                    "type": "string",
                    "minLength": 1,
                    "description": "This deployment does not run launch-run copies; run the agent without copies."
                  },
                  "outcome": {
                    "type": "string",
                    "const": "not_started"
                  }
                }
              }
            }
          }
        ]
      },
      "LaunchSettings": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "launch_id",
          "source",
          "placement",
          "secrets",
          "added_secrets"
        ],
        "description": "What one launch asked for, recorded when it was created. Choices and names only: secret\nvalues are never recorded.\n",
        "properties": {
          "launch_id": {
            "type": "string",
            "minLength": 1
          },
          "source": {
            "description": "The catalog agent, or the caller's own repository or image.",
            "oneOf": [
              {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "kind",
                  "agent"
                ],
                "properties": {
                  "kind": {
                    "const": "agent"
                  },
                  "agent": {
                    "type": "string",
                    "minLength": 1
                  }
                }
              },
              {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "kind",
                  "name",
                  "repository",
                  "ref",
                  "checkout"
                ],
                "properties": {
                  "kind": {
                    "const": "repository"
                  },
                  "name": {
                    "type": "string",
                    "minLength": 1
                  },
                  "repository": {
                    "type": "string",
                    "minLength": 1
                  },
                  "ref": {
                    "type": "string",
                    "minLength": 1
                  },
                  "path": {
                    "type": "string",
                    "minLength": 1,
                    "description": "Manifest path inside the repository, when the launch read one."
                  },
                  "checkout": {
                    "type": "boolean",
                    "description": "True when the repository was checked out and the command run in it, rather than read for a manifest."
                  },
                  "command": {
                    "type": "string",
                    "minLength": 1
                  }
                }
              },
              {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "kind",
                  "name",
                  "image"
                ],
                "properties": {
                  "kind": {
                    "const": "image"
                  },
                  "name": {
                    "type": "string",
                    "minLength": 1
                  },
                  "image": {
                    "type": "string",
                    "minLength": 1
                  },
                  "command": {
                    "type": "string",
                    "minLength": 1
                  }
                }
              },
              {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "kind",
                  "name"
                ],
                "description": "An inline manifest that names neither a repository nor an image (for example a Dockerfile build).",
                "properties": {
                  "kind": {
                    "const": "manifest"
                  },
                  "name": {
                    "type": "string",
                    "minLength": 1
                  }
                }
              }
            ]
          },
          "placement": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "mode",
              "providers"
            ],
            "properties": {
              "mode": {
                "type": "string",
                "enum": [
                  "picks",
                  "chosen"
                ],
                "description": "picks when BoxRouter chose the provider; chosen when the caller named one or more."
              },
              "providers": {
                "type": "array",
                "items": {
                  "type": "string",
                  "minLength": 1
                },
                "description": "The providers the caller allowed; empty when BoxRouter picked."
              }
            }
          },
          "secrets": {
            "type": "array",
            "items": {
              "type": "string",
              "minLength": 1
            },
            "description": "Names of every secret the launch used, declared by the agent or added by the caller."
          },
          "added_secrets": {
            "type": "array",
            "items": {
              "type": "string",
              "minLength": 1
            },
            "description": "Names the caller added to the agent's own (`--secret` on the command line)."
          }
        }
      },
      "LaunchCommand": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "launch_id",
          "sandbox_id",
          "command_started_at",
          "timeout_seconds",
          "state",
          "exit_code"
        ],
        "description": "The bounded state of a launch's unattended command. This handle excludes command text,\nenvironment variables, private process identity and all output. `unknown` is returned\nwhen the command outcome cannot be confirmed.\n",
        "properties": {
          "launch_id": {
            "type": "string",
            "minLength": 1
          },
          "sandbox_id": {
            "type": "string",
            "minLength": 1
          },
          "command_started_at": {
            "type": "string",
            "format": "date-time"
          },
          "timeout_seconds": {
            "type": "integer",
            "minimum": 1,
            "description": "Fixed command runtime bound set when the command started."
          },
          "state": {
            "type": "string",
            "enum": [
              "running",
              "exited",
              "timed_out",
              "unknown"
            ],
            "x-boxrouter-open-enum": true,
            "description": "Known observations. Clients must preserve unrecognized values for forward compatibility."
          },
          "exit_code": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Confirmed exit status for exited or timed_out commands; null while running or when the outcome is unknown."
          }
        }
      },
      "LaunchRunList": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "available",
          "runs",
          "next_cursor",
          "total_copies",
          "live_copies"
        ],
        "description": "One newest-first page of run summaries. The totals cover every run in the authenticated workspace, not only this page. When `available` is false this deployment does not run copies: the page is empty, the totals are zero, and the other launch-run operations answer 409 capability_unavailable.",
        "properties": {
          "available": {
            "type": "boolean",
            "description": "False when this deployment does not run launch-run copies; true otherwise."
          },
          "runs": {
            "type": "array",
            "maxItems": 50,
            "items": {
              "$ref": "#/components/schemas/LaunchRunSummary"
            }
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "maxLength": 1024,
            "description": "Opaque cursor for the next page; null on the last page."
          },
          "total_copies": {
            "type": "integer",
            "minimum": 0,
            "description": "Copies requested across all of the workspace's runs."
          },
          "live_copies": {
            "type": "integer",
            "minimum": 0,
            "description": "Copies across all of the workspace's runs whose sandboxes have not been confirmed absent."
          }
        }
      },
      "LaunchRunSummary": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "agent_name",
          "copies",
          "desired_state",
          "created_at",
          "live_copies",
          "providers"
        ],
        "description": "Lightweight run row for listLaunchRuns; copy items and command data are not included.",
        "properties": {
          "id": {
            "type": "string",
            "minLength": 1
          },
          "agent_name": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "description": "Manifest name of the resolved catalog agent or inline manifest stored with the run; null when the stored run has none. No other launch request or manifest data is returned."
          },
          "copies": {
            "type": "integer",
            "minimum": 1
          },
          "desired_state": {
            "type": "string",
            "enum": [
              "running",
              "stopped"
            ],
            "x-boxrouter-open-enum": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "live_copies": {
            "type": "integer",
            "minimum": 0,
            "description": "Copies of this run whose sandboxes have not been confirmed absent, including stopping copies."
          },
          "providers": {
            "type": "array",
            "uniqueItems": true,
            "items": {
              "type": "string",
              "minLength": 1
            },
            "description": "Sorted distinct providers of the workspace-owned sandboxes attached to this run's copies; empty until a sandbox is attached."
          }
        }
      },
      "LaunchRunRequest": {
        "type": "object",
        "unevaluatedProperties": false,
        "description": "One unattended launch run. Uses the canonical launch request fields and requires copies; request-only credential values are refused by the server before reservation.",
        "allOf": [
          {
            "$ref": "#/components/schemas/LaunchRequestFields"
          },
          {
            "type": "object",
            "required": [
              "copies"
            ],
            "properties": {
              "copies": {
                "type": "integer",
                "minimum": 1,
                "description": "Number of independently managed copies to reserve atomically."
              }
            }
          }
        ]
      },
      "LaunchRunDocument": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "agent_name",
          "copies",
          "desired_state",
          "created_at",
          "items"
        ],
        "description": "Plain metadata-only run response. It contains neither command observations nor output fields; GET is a provider-free read unless include=command is explicitly selected.",
        "properties": {
          "id": {
            "type": "string",
            "minLength": 1
          },
          "agent_name": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "description": "Manifest name of the resolved catalog agent or inline manifest stored with the run; null when the stored run has none. No other launch request or manifest data is returned."
          },
          "copies": {
            "type": "integer",
            "minimum": 1
          },
          "desired_state": {
            "type": "string",
            "enum": [
              "running",
              "stopped"
            ],
            "x-boxrouter-open-enum": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/LaunchRunItem"
            }
          }
        }
      },
      "LaunchRunItem": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "index",
          "status",
          "sandbox_id",
          "provider",
          "error",
          "exit_code",
          "finished_at"
        ],
        "description": "One ordered copy's public lifecycle metadata; output contents are never included.",
        "properties": {
          "index": {
            "type": "integer",
            "minimum": 0
          },
          "status": {
            "type": "string",
            "enum": [
              "queued",
              "preparing",
              "started",
              "start_failed",
              "stopping",
              "stopped",
              "finished",
              "unknown"
            ]
          },
          "sandbox_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "provider": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "description": "Provider of the workspace-owned sandbox attached to this copy; null until a sandbox is attached."
          },
          "error": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/LaunchRunCopyError"
              },
              {
                "type": "null"
              }
            ]
          },
          "exit_code": {
            "type": [
              "integer",
              "null"
            ]
          },
          "finished_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        }
      },
      "LaunchRunCopyError": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "code",
          "message",
          "fix"
        ],
        "properties": {
          "code": {
            "type": [
              "string",
              "null"
            ]
          },
          "message": {
            "type": [
              "string",
              "null"
            ]
          },
          "fix": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "LaunchRunRequestErrorResponse": {
        "anyOf": [
          {
            "$ref": "#/components/schemas/InvalidRequestErrorResponse"
          },
          {
            "$ref": "#/components/schemas/SecretMissingErrorResponse"
          },
          {
            "$ref": "#/components/schemas/UnsupportedFeatureErrorResponse"
          }
        ]
      },
      "UnsupportedFeatureErrorResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/ApiErrorResponse"
          },
          {
            "type": "object",
            "properties": {
              "error": {
                "type": "object",
                "required": [
                  "code",
                  "details"
                ],
                "properties": {
                  "code": {
                    "type": "string",
                    "const": "unsupported_feature"
                  },
                  "details": {
                    "type": "object",
                    "required": [
                      "feature"
                    ],
                    "properties": {
                      "feature": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            }
          }
        ]
      },
      "LaunchRunWithCommand": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "agent_name",
          "copies",
          "desired_state",
          "created_at",
          "items"
        ],
        "description": "Run response selected by GET include=command. The command member contains only bounded state and exit code; command text and collected output are never returned.",
        "properties": {
          "id": {
            "type": "string",
            "minLength": 1
          },
          "agent_name": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "description": "Manifest name of the resolved catalog agent or inline manifest stored with the run; null when the stored run has none. No other launch request or manifest data is returned."
          },
          "copies": {
            "type": "integer",
            "minimum": 1
          },
          "desired_state": {
            "type": "string",
            "enum": [
              "running",
              "stopped"
            ],
            "x-boxrouter-open-enum": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "items": {
            "type": "array",
            "items": {
              "anyOf": [
                {
                  "$ref": "#/components/schemas/LaunchRunItem"
                },
                {
                  "$ref": "#/components/schemas/LaunchRunItemWithCommand"
                }
              ]
            }
          }
        }
      },
      "LaunchRunItemWithCommand": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "index",
          "status",
          "sandbox_id",
          "provider",
          "error",
          "exit_code",
          "finished_at"
        ],
        "description": "Copy metadata plus an opt-in bounded command observation.",
        "properties": {
          "index": {
            "type": "integer",
            "minimum": 0
          },
          "status": {
            "type": "string",
            "enum": [
              "queued",
              "preparing",
              "started",
              "start_failed",
              "stopping",
              "stopped",
              "finished",
              "unknown"
            ]
          },
          "sandbox_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "provider": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "description": "Provider of the workspace-owned sandbox attached to this copy; null until a sandbox is attached."
          },
          "error": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/LaunchRunCopyError"
              },
              {
                "type": "null"
              }
            ]
          },
          "exit_code": {
            "type": [
              "integer",
              "null"
            ]
          },
          "finished_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "command": {
            "$ref": "#/components/schemas/LaunchRunCommandObservation"
          }
        }
      },
      "LaunchRunCommandObservation": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "status",
          "exit_code"
        ],
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "running",
              "exited",
              "timed_out",
              "unknown"
            ],
            "x-boxrouter-open-enum": true,
            "description": "Bounded command observation only. The response never includes command text, output, provider handles, or credential values. Clients preserve an unrecognized observation state for forward compatibility."
          },
          "exit_code": {
            "type": [
              "integer",
              "null"
            ]
          }
        }
      },
      "LaunchRunStopAccepted": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "desired_state",
          "stopped_at"
        ],
        "properties": {
          "id": {
            "type": "string",
            "minLength": 1
          },
          "desired_state": {
            "type": "string",
            "const": "stopped"
          },
          "stopped_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "LaunchRunCopyDestroyAccepted": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "run_id",
          "copy_index",
          "status"
        ],
        "description": "Acknowledges a durable cleanup request for one copy. `stopping` is not confirmation that the sandbox is gone; read getLaunchRun for the copy's current status.",
        "properties": {
          "run_id": {
            "type": "string",
            "minLength": 1
          },
          "copy_index": {
            "type": "integer",
            "minimum": 0
          },
          "status": {
            "type": "string",
            "const": "stopping"
          }
        }
      },
      "RepositoryAccess": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "repo",
          "readable",
          "visibility",
          "sha",
          "files",
          "recipe"
        ],
        "description": "Whether the workspace can read one repository, and what a launch would do with it.",
        "properties": {
          "repo": {
            "type": "string",
            "description": "Repository as owner/name."
          },
          "readable": {
            "type": "boolean"
          },
          "visibility": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "public",
              "private",
              null
            ],
            "description": "public, or private when read through the workspace's GitHub connection; null when unreadable."
          },
          "sha": {
            "type": [
              "string",
              "null"
            ],
            "description": "Commit the checked ref points at; null when unreadable."
          },
          "files": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "string"
            },
            "description": "Top-level entries at sha, directories ending in a slash; null when unreadable or the listing failed."
          },
          "recipe": {
            "type": [
              "object",
              "null"
            ],
            "additionalProperties": false,
            "required": [
              "kind",
              "hint"
            ],
            "properties": {
              "kind": {
                "type": "string",
                "enum": [
                  "manifest",
                  "dockerfile",
                  "node",
                  "python",
                  "plain"
                ]
              },
              "hint": {
                "type": "string",
                "description": "One sentence saying which setup applies."
              },
              "command": {
                "type": "string",
                "description": "Start command when one is known."
              }
            }
          },
          "code": {
            "type": "string",
            "description": "Machine-readable refusal code; present only when readable is false."
          },
          "message": {
            "type": "string",
            "description": "Why the repository cannot be read; present only when readable is false."
          },
          "fix": {
            "type": "string",
            "description": "What to do about it; present only when readable is false."
          }
        }
      },
      "GitHubInstallationPage": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "data",
          "next_cursor"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/GitHubInstallation"
            }
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "maxLength": 128,
            "pattern": "^[^\\u0000]*$"
          }
        }
      },
      "GitHubInstallation": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "account_login",
          "account_type",
          "repository_selection",
          "repository_count",
          "linked_at",
          "state"
        ],
        "properties": {
          "id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128,
            "pattern": "^[^\\u0000]*$"
          },
          "account_login": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255
          },
          "account_type": {
            "type": "string",
            "enum": [
              "user",
              "organization"
            ]
          },
          "repository_selection": {
            "type": "string",
            "enum": [
              "all",
              "selected",
              "unknown"
            ]
          },
          "repository_count": {
            "type": "integer",
            "minimum": 0
          },
          "linked_at": {
            "type": "string",
            "format": "date-time"
          },
          "state": {
            "type": "string",
            "enum": [
              "active",
              "unavailable"
            ]
          }
        }
      },
      "IdempotencyKeyValue": {
        "type": "string",
        "minLength": 1,
        "maxLength": 128,
        "description": "Stable identifier for one logical mutation."
      },
      "GitHubRepositoryPage": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "data",
          "next_cursor"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/GitHubRepository"
            }
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "maxLength": 128,
            "pattern": "^[^\\u0000]*$"
          }
        }
      },
      "GitHubRepository": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "installation_id",
          "full_name",
          "default_branch",
          "administrator",
          "connection_state"
        ],
        "properties": {
          "id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128,
            "pattern": "^[^\\u0000]*$"
          },
          "installation_id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128,
            "pattern": "^[^\\u0000]*$"
          },
          "full_name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 512
          },
          "default_branch": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "maxLength": 255
          },
          "administrator": {
            "type": "boolean",
            "description": "Whether current GitHub permissions prove repository-administrator authority."
          },
          "private": {
            "type": "boolean",
            "description": "Whether GitHub reports the repository as private."
          },
          "connection_state": {
            "type": "string",
            "enum": [
              "verified",
              "permission_required",
              "unavailable"
            ]
          }
        }
      },
      "ActionsRepositoriesResponse": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "data"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ActionsRepositorySettingsEntry"
            }
          }
        }
      },
      "ActionsRepositorySettingsEntry": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "settings",
          "etag"
        ],
        "properties": {
          "etag": {
            "type": "string",
            "maxLength": 256,
            "description": "The strong settings revision the single-repository GET carries in its ETag header; send it as If-Match for updates once the record exists."
          },
          "settings": {
            "$ref": "#/components/schemas/ActionsRepositorySettings"
          }
        }
      },
      "ActionsRepositorySettings": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "repository_id",
          "exists",
          "enabled",
          "policy_id",
          "state",
          "default_label",
          "revision",
          "updated_at"
        ],
        "properties": {
          "resolved_profile": {
            "type": "string",
            "enum": [
              "linux-basic",
              "full"
            ],
            "x-boxrouter-open-enum": true,
            "readOnly": true,
            "description": "Effective software profile resolved by GET from the saved repository policy, or linux-basic when no policy is selected. With exists=false this is the default, not a saved configuration. This does not claim image or route readiness. May be absent on older servers and write or idempotent replay responses; GET is authoritative. It does not change the settings CAS token."
          },
          "repository_id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128,
            "pattern": "^[^\\u0000]*$"
          },
          "exists": {
            "type": "boolean",
            "description": "False only when no settings record exists; omit If-Match for its first write. True means If-Match is required."
          },
          "enabled": {
            "type": "boolean"
          },
          "policy_id": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "maxLength": 128,
            "pattern": "^[^\\u0000]*$"
          },
          "state": {
            "type": "string",
            "enum": [
              "disabled",
              "preparing",
              "ready",
              "attention_required"
            ]
          },
          "reason_code": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 128,
            "pattern": "^[a-z][a-z0-9_.-]{0,127}$",
            "description": "Optional machine-readable reason for a non-ready repository state."
          },
          "message": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "maxLength": 512,
            "description": "Optional plain-language explanation of the current repository state."
          },
          "link_target": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "byok",
              "credits",
              null
            ],
            "description": "Optional destination when the repository state can be fixed in another page."
          },
          "default_label": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128,
            "description": "The repository's selected BoxRouter runner label."
          },
          "revision": {
            "type": "integer",
            "minimum": 1
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "UpdateActionsRepository": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "enabled"
        ],
        "properties": {
          "enabled": {
            "type": "boolean"
          },
          "policy_id": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "maxLength": 128,
            "pattern": "^[^\\u0000]*$",
            "description": "Optional workspace-owned policy. Omission or null selects automatic safe defaults."
          }
        }
      },
      "RoutingSettings": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "mode",
          "provider_order",
          "excluded_providers",
          "allow_fallbacks",
          "prevent_overrides",
          "provider_funding",
          "section_etags"
        ],
        "properties": {
          "mode": {
            "$ref": "#/components/schemas/mode"
          },
          "provider_order": {
            "$ref": "#/components/schemas/provider_order"
          },
          "excluded_providers": {
            "$ref": "#/components/schemas/excluded_providers"
          },
          "allow_fallbacks": {
            "$ref": "#/components/schemas/allow_fallbacks"
          },
          "prevent_overrides": {
            "$ref": "#/components/schemas/prevent_overrides"
          },
          "provider_funding": {
            "type": "object",
            "propertyNames": {
              "$ref": "#/components/schemas/ProviderSlug"
            },
            "additionalProperties": {
              "$ref": "#/components/schemas/ProviderFunding"
            }
          },
          "section_etags": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "routing",
              "provider_funding"
            ],
            "properties": {
              "routing": {
                "type": "string",
                "minLength": 1
              },
              "provider_funding": {
                "type": "object",
                "propertyNames": {
                  "$ref": "#/components/schemas/ProviderSlug"
                },
                "additionalProperties": {
                  "type": "string",
                  "minLength": 1
                }
              }
            },
            "description": "Opaque independent Routing and provider validators, never a document-wide ETag."
          }
        }
      },
      "mode": {
        "type": "string",
        "enum": [
          "automatic",
          "cheapest",
          "fastest",
          "custom"
        ],
        "x-boxrouter-choices": {
          "automatic": {
            "label": "Auto",
            "line": "A random draw weighted toward lower hourly price."
          },
          "cheapest": {
            "label": "Cheapest",
            "line": "Lowest hourly price first.",
            "measure": "price",
            "better": "lower"
          },
          "fastest": {
            "label": "Fastest",
            "line": "Shortest run time measured on reference workloads first.",
            "measure": "time",
            "better": "lower"
          },
          "custom": {
            "label": "Custom",
            "line": "Your exact provider order, top to bottom."
          }
        }
      },
      "provider_order": {
        "type": "array",
        "uniqueItems": true,
        "description": "Stored in every mode; newly supported providers append in deployment order and start enabled.",
        "items": {
          "$ref": "#/components/schemas/ProviderSlug"
        }
      },
      "ProviderSlug": {
        "type": "string",
        "minLength": 1,
        "maxLength": 64,
        "pattern": "^[a-z][a-z0-9-]*$"
      },
      "excluded_providers": {
        "type": "array",
        "uniqueItems": true,
        "description": "Hard deny-list; connecting a key does not clear its provider's exclusion.",
        "items": {
          "$ref": "#/components/schemas/ProviderSlug"
        }
      },
      "allow_fallbacks": {
        "type": "boolean",
        "description": "After a definite pre-create refusal, try only later frozen routes in the same Prioritized, Credits or Fallback group; never retry unknown outcomes or created jobs."
      },
      "prevent_overrides": {
        "type": "boolean",
        "default": false,
        "description": "Reject requests containing preferences.order, preferences.sort or preferences.allow_fallbacks even when identical to the default; hard request restrictions still narrow."
      },
      "ProviderFunding": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "funding_order"
        ],
        "description": "Account IDs must belong to this workspace and provider, and must be unique.\nKeys above Credits are Prioritized; keys below it are Fallback. An unavailable\nmanaged provider keeps the managed row, its position and stored credits value\nwithout becoming routable. Never-offered providers have no managed row or credits.\nA later managed offer appends an off row after keys. A new key inserts last in\nPrioritized even in Custom; deleting a key removes that row. Account mutations\nupdate only this provider section and its ETag atomically with the account.\n",
        "properties": {
          "funding_order": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FundingEntry"
            }
          },
          "credits": {
            "type": "boolean",
            "description": "False preserves the managed row and position but makes it unusable."
          }
        },
        "allOf": [
          {
            "if": {
              "required": [
                "credits"
              ]
            },
            "then": {
              "properties": {
                "funding_order": {
                  "contains": {
                    "$ref": "#/components/schemas/ManagedFunding"
                  },
                  "minContains": 1,
                  "maxContains": 1
                }
              }
            }
          },
          {
            "if": {
              "properties": {
                "funding_order": {
                  "contains": {
                    "$ref": "#/components/schemas/ManagedFunding"
                  }
                }
              },
              "required": [
                "funding_order"
              ]
            },
            "then": {
              "required": [
                "credits"
              ]
            }
          },
          {
            "not": {
              "properties": {
                "funding_order": {
                  "contains": {
                    "$ref": "#/components/schemas/ManagedFunding"
                  },
                  "minContains": 2
                }
              }
            }
          }
        ]
      },
      "FundingEntry": {
        "oneOf": [
          {
            "$ref": "#/components/schemas/FundingAccount"
          },
          {
            "$ref": "#/components/schemas/ManagedFunding"
          }
        ]
      },
      "FundingAccount": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "account_id"
        ],
        "properties": {
          "account_id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128
          }
        }
      },
      "ManagedFunding": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "supply"
        ],
        "properties": {
          "supply": {
            "type": "string",
            "const": "managed"
          }
        }
      },
      "RoutingSettingsUpdate": {
        "oneOf": [
          {
            "$ref": "#/components/schemas/RoutingSectionUpdate"
          },
          {
            "$ref": "#/components/schemas/ProviderFundingSectionUpdate"
          }
        ],
        "discriminator": {
          "propertyName": "section",
          "mapping": {
            "routing": "#/components/schemas/RoutingSectionUpdate",
            "provider_funding": "#/components/schemas/ProviderFundingSectionUpdate"
          }
        }
      },
      "RoutingSectionUpdate": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "section",
          "routing"
        ],
        "description": "Routing update. Fields omitted from `routing` keep their stored values; the merged\nsection is validated as a complete Routing section before it is written.\n",
        "properties": {
          "section": {
            "type": "string",
            "const": "routing"
          },
          "routing": {
            "$ref": "#/components/schemas/RoutingFieldsUpdate"
          }
        }
      },
      "RoutingFieldsUpdate": {
        "type": "object",
        "additionalProperties": false,
        "minProperties": 1,
        "description": "Partial Routing section: send only the fields to change. Every omitted field keeps\nits stored value. The merged section is validated as a complete Routing section.\n",
        "$defs": {
          "complete": {
            "$ref": "#/components/schemas/RoutingFields"
          }
        },
        "properties": {
          "mode": {
            "$ref": "#/components/schemas/mode"
          },
          "provider_order": {
            "$ref": "#/components/schemas/provider_order"
          },
          "excluded_providers": {
            "$ref": "#/components/schemas/excluded_providers"
          },
          "allow_fallbacks": {
            "$ref": "#/components/schemas/allow_fallbacks"
          },
          "prevent_overrides": {
            "$ref": "#/components/schemas/prevent_overrides"
          }
        }
      },
      "RoutingFields": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "mode",
          "provider_order",
          "excluded_providers",
          "allow_fallbacks",
          "prevent_overrides"
        ],
        "properties": {
          "mode": {
            "type": "string",
            "enum": [
              "automatic",
              "cheapest",
              "fastest",
              "custom"
            ],
            "x-boxrouter-choices": {
              "automatic": {
                "label": "Auto",
                "line": "A random draw weighted toward lower hourly price."
              },
              "cheapest": {
                "label": "Cheapest",
                "line": "Lowest hourly price first.",
                "measure": "price",
                "better": "lower"
              },
              "fastest": {
                "label": "Fastest",
                "line": "Shortest run time measured on reference workloads first.",
                "measure": "time",
                "better": "lower"
              },
              "custom": {
                "label": "Custom",
                "line": "Your exact provider order, top to bottom."
              }
            }
          },
          "provider_order": {
            "type": "array",
            "uniqueItems": true,
            "description": "Stored in every mode; newly supported providers append in deployment order and start enabled.",
            "items": {
              "$ref": "#/components/schemas/ProviderSlug"
            }
          },
          "excluded_providers": {
            "type": "array",
            "uniqueItems": true,
            "description": "Hard deny-list; connecting a key does not clear its provider's exclusion.",
            "items": {
              "$ref": "#/components/schemas/ProviderSlug"
            }
          },
          "allow_fallbacks": {
            "type": "boolean",
            "description": "After a definite pre-create refusal, try only later frozen routes in the same Prioritized, Credits or Fallback group; never retry unknown outcomes or created jobs."
          },
          "prevent_overrides": {
            "type": "boolean",
            "default": false,
            "description": "Reject requests containing preferences.order, preferences.sort or preferences.allow_fallbacks even when identical to the default; hard request restrictions still narrow."
          }
        }
      },
      "ProviderFundingSectionUpdate": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "section",
          "provider",
          "funding"
        ],
        "description": "One provider's funding update. Fields omitted from `funding` keep their stored values;\nthe merged section is validated as a complete provider funding section before it is written.\n",
        "properties": {
          "section": {
            "type": "string",
            "const": "provider_funding"
          },
          "provider": {
            "$ref": "#/components/schemas/ProviderSlug"
          },
          "funding": {
            "$ref": "#/components/schemas/ProviderFundingUpdate"
          }
        }
      },
      "ProviderFundingUpdate": {
        "type": "object",
        "additionalProperties": false,
        "minProperties": 1,
        "description": "Partial provider funding section: send only the fields to change. Every omitted\nfield keeps its stored value. The merged section is validated as a complete\nprovider funding section, including its Credits and account invariants.\n",
        "properties": {
          "funding_order": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FundingEntry"
            }
          },
          "credits": {
            "type": "boolean",
            "description": "False preserves the managed row and position but makes it unusable."
          }
        }
      },
      "RoutingPreview": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "learning",
          "can_start",
          "skipped",
          "worst_case_usd",
          "credits_cover_cpu"
        ],
        "properties": {
          "learning": {
            "type": "string",
            "enum": [
              "on",
              "off"
            ],
            "x-boxrouter-open-enum": true
          },
          "can_start": {
            "type": "boolean"
          },
          "skipped": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RoutingSkipped"
            }
          },
          "worst_case_usd": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RoutingSizeQuote"
            },
            "description": "Per-Actions-size quoted holds; empty if no managed quote is available."
          },
          "credits_cover_cpu": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0,
            "description": "Largest quoted Actions CPU floor covered by balance; null when unavailable."
          }
        }
      },
      "RoutingSkipped": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "provider",
          "reason"
        ],
        "oneOf": [
          {
            "required": [
              "account_id"
            ]
          },
          {
            "required": [
              "supply"
            ]
          }
        ],
        "properties": {
          "provider": {
            "$ref": "#/components/schemas/ProviderSlug"
          },
          "account_id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128
          },
          "supply": {
            "type": "string",
            "const": "managed"
          },
          "reason": {
            "type": "string",
            "enum": [
              "byok_key_invalid",
              "credits_exhausted",
              "credits_below_hold",
              "managed_provider_disabled",
              "spend_limit_exceeded"
            ],
            "x-boxrouter-open-enum": true
          },
          "action": {
            "type": "string",
            "enum": [
              "add_key",
              "fix_key",
              "use_credits"
            ],
            "x-boxrouter-open-enum": true,
            "description": "Permitted recovery action, omitted when none is available."
          }
        }
      },
      "RoutingSizeQuote": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "size",
          "worst_case_usd"
        ],
        "properties": {
          "size": {
            "type": "string",
            "minLength": 1,
            "description": "Published Actions runner size label."
          },
          "worst_case_usd": {
            "type": "string",
            "pattern": "^(0|[1-9][0-9]*)(\\.[0-9]+)?$",
            "description": "Full fixed-lifetime hold (run plus pickup) in USD, not a workspace cap."
          }
        }
      },
      "ActionsReadinessResponse": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "readiness"
        ],
        "properties": {
          "readiness": {
            "$ref": "#/components/schemas/ActionsReadiness"
          },
          "runner_catalog": {
            "$ref": "#/components/schemas/ActionsRunnerCatalog",
            "description": "Optional for compatibility with older servers; consumers must not invent recommended labels when absent. Prefer the `getActionsRunnerCatalog` operation, which serves the same document cacheably; this copy is retained only for older clients."
          }
        }
      },
      "ActionsReadiness": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "runners_ready"
        ],
        "properties": {
          "profile": {
            "type": "string",
            "enum": [
              "linux-basic",
              "full"
            ],
            "x-boxrouter-open-enum": true,
            "description": "Software profile covered by this readiness evidence. When repository-scoped, this is the saved profile for that repository; otherwise it is the workspace's basic readiness view."
          },
          "runners_ready": {
            "type": "boolean"
          },
          "providers": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ActionsReadinessProvider"
            }
          },
          "runner_labels": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ActionsRunnerLabel"
            }
          },
          "reason_code": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "funding_none",
              "funding_unavailable",
              "github_app_suspended",
              "repository_unavailable",
              null
            ],
            "x-boxrouter-open-enum": true
          },
          "disk_min_mib": {
            "type": "integer",
            "minimum": 1,
            "description": "Configured minimum disk floor for the selected profile in MiB. This is not provider allocation or observed free disk."
          },
          "message": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "maxLength": 512
          },
          "link_target": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "byok",
              "credits",
              null
            ]
          }
        }
      },
      "ActionsReadinessProvider": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "provider",
          "provider_label",
          "account_id",
          "account_label",
          "supply",
          "ready",
          "region",
          "size",
          "reason_code",
          "message",
          "link_target"
        ],
        "properties": {
          "profile": {
            "type": "string",
            "enum": [
              "linux-basic",
              "full"
            ],
            "x-boxrouter-open-enum": true,
            "description": "Software profile covered by this readiness evidence. When repository-scoped, this is the saved profile for that repository; otherwise it is the workspace's basic readiness view."
          },
          "provider": {
            "type": "string",
            "minLength": 1,
            "maxLength": 64,
            "pattern": "^[a-z][a-z0-9-]*$"
          },
          "provider_label": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128
          },
          "account_id": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "maxLength": 128
          },
          "account_label": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "maxLength": 128
          },
          "supply": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "byok",
              "managed",
              null
            ]
          },
          "ready": {
            "type": "boolean"
          },
          "region": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "maxLength": 128
          },
          "size": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/ActionsMachineSize"
              },
              {
                "type": "null"
              }
            ]
          },
          "cpu_options": {
            "type": "array",
            "uniqueItems": true,
            "items": {
              "type": "integer",
              "minimum": 1
            }
          },
          "vcpu_options": {
            "deprecated": true,
            "description": "Temporary compatibility field. Use cpu_options.",
            "type": "array",
            "uniqueItems": true,
            "items": {
              "type": "integer",
              "minimum": 1
            }
          },
          "unavailable_shapes": {
            "type": "array",
            "description": "Runner sizes this route cannot serve, each with its own cause, so a size missing from cpu_options explains itself. A size is listed when the provider's declaration refuses it, when its image failed terminally, or when its image check is still pending. Omitted by older servers; empty when every size is available.",
            "maxItems": 16,
            "items": {
              "$ref": "#/components/schemas/ActionsUnavailableShape"
            }
          },
          "max_job_minutes": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1
          },
          "reason_code": {
            "type": [
              "string",
              "null"
            ],
            "description": "repository_policy means no route on this provider matches the repository policy; needs_image_verification means image verification is pending; local_preview_unverified means this local preview cannot verify images.",
            "enum": [
              "provider_not_connected",
              "provider_unsupported_for_actions",
              "byok_key_invalid",
              "credits_exhausted",
              "provider_outage",
              "provider_capacity",
              "repository_policy",
              "needs_image_verification",
              "local_preview_unverified",
              null
            ],
            "x-boxrouter-open-enum": true
          },
          "message": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "maxLength": 512
          },
          "link_target": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "byok",
              "credits",
              null
            ]
          }
        }
      },
      "ActionsMachineSize": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "cpu",
          "memory_mib"
        ],
        "properties": {
          "cpu": {
            "type": "number",
            "exclusiveMinimum": 0,
            "description": "Normalized virtual CPU count."
          },
          "memory_mib": {
            "type": "integer",
            "minimum": 1,
            "description": "Normalized memory in MiB."
          }
        }
      },
      "ActionsUnavailableShape": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "cpu",
          "memory_mib",
          "reason_code",
          "message"
        ],
        "properties": {
          "cpu": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1,
            "description": "Requested vCPU floor; null for the memory-selected size."
          },
          "memory_mib": {
            "type": "integer",
            "minimum": 1
          },
          "reason_code": {
            "type": "string",
            "minLength": 1,
            "maxLength": 64,
            "description": "resource_mismatch means the provider declares smaller sandboxes; needs_image_verification means the size is still being checked; any other stable code (resource_limit, image_copy_failed, image_preparation_failed, probe_failed) is the latest terminal image failure."
          },
          "message": {
            "type": "string",
            "minLength": 1,
            "maxLength": 512
          }
        }
      },
      "ActionsRunnerLabel": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "label",
          "providers"
        ],
        "properties": {
          "profile": {
            "type": "string",
            "enum": [
              "linux-basic",
              "full"
            ],
            "x-boxrouter-open-enum": true,
            "description": "Software profile covered by this runner label's readiness evidence."
          },
          "label": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128
          },
          "objective": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "any",
              null
            ],
            "x-boxrouter-choices": {
              "any": {
                "label": "Any Fit",
                "line": "on any available provider with this size."
              }
            },
            "description": "Always `any`; runner labels no longer select an ordering objective. Routing preference comes from the workspace Routing setting."
          },
          "size": {
            "$ref": "#/components/schemas/ActionsRunnerLabelSize"
          },
          "providers": {
            "type": "array",
            "uniqueItems": true,
            "items": {
              "type": "string",
              "minLength": 1,
              "maxLength": 64,
              "pattern": "^[a-z][a-z0-9-]*$"
            }
          },
          "objective_ranked": {
            "type": "boolean"
          },
          "vcpu": {
            "deprecated": true,
            "description": "Temporary compatibility field. Use size.cpu.",
            "type": "number",
            "exclusiveMinimum": 0
          },
          "memory_gb": {
            "deprecated": true,
            "description": "Temporary compatibility field. Use size.memory_mib.",
            "type": "number",
            "exclusiveMinimum": 0
          },
          "os_label": {
            "deprecated": true,
            "description": "Temporary compatibility field. Derive this from the runner label.",
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "maxLength": 128
          }
        },
        "anyOf": [
          {
            "required": [
              "size"
            ]
          },
          {
            "required": [
              "vcpu",
              "memory_gb"
            ]
          }
        ]
      },
      "ActionsRunnerLabelSize": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "memory_mib"
        ],
        "properties": {
          "cpu": {
            "type": "number",
            "exclusiveMinimum": 0,
            "description": "Normalized virtual CPU count when the provider declares it. Omitted for memory-selected labels without a CPU floor."
          },
          "memory_mib": {
            "type": "integer",
            "minimum": 1,
            "description": "Normalized memory in MiB."
          }
        }
      },
      "ActionsRunnerCatalog": {
        "description": "Domain-owned recommended labels and requested resource floors. This catalog does not assert live route availability or verified software. A label selects the machine size and image tier only; routing preference comes from the workspace Routing setting. Removed label spellings are not accepted.",
        "type": "object",
        "additionalProperties": false,
        "required": [
          "version",
          "runners",
          "profiles",
          "profile_source",
          "standard_labels",
          "default_label"
        ],
        "properties": {
          "version": {
            "type": "integer",
            "const": 1
          },
          "runners": {
            "type": "array",
            "minItems": 1,
            "items": {
              "$ref": "#/components/schemas/ActionsRunnerCatalogEntry"
            }
          },
          "profiles": {
            "type": "array",
            "minItems": 1,
            "uniqueItems": true,
            "items": {
              "type": "string",
              "minLength": 1
            }
          },
          "profile_source": {
            "type": "string",
            "const": "runner_label"
          },
          "standard_labels": {
            "type": "array",
            "uniqueItems": true,
            "items": {
              "type": "string",
              "minLength": 1
            }
          },
          "default_label": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          }
        }
      },
      "ActionsRunnerCatalogEntry": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "label",
          "shape",
          "profile"
        ],
        "properties": {
          "label": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200,
            "pattern": "^[A-Za-z0-9][A-Za-z0-9._-]*$"
          },
          "shape": {
            "$ref": "#/components/schemas/ActionsRunnerCatalogShape"
          },
          "profile": {
            "type": "string",
            "enum": [
              "linux-basic",
              "full"
            ],
            "x-boxrouter-open-enum": true,
            "description": "Image tier this label selects; `full` is admitted only where the workspace's allowed_profiles covers it."
          }
        }
      },
      "ActionsRunnerCatalogShape": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "name",
          "cpu",
          "memory_mib",
          "architecture",
          "operating_system"
        ],
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1
          },
          "cpu": {
            "type": "integer",
            "minimum": 1
          },
          "memory_mib": {
            "type": "integer",
            "minimum": 1
          },
          "architecture": {
            "type": "string",
            "minLength": 1
          },
          "operating_system": {
            "type": "string",
            "minLength": 1
          }
        }
      },
      "ActionsPolicyPage": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "data",
          "next_cursor"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ActionsPolicy"
            }
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "maxLength": 128,
            "pattern": "^[^\\u0000]*$"
          }
        }
      },
      "ActionsPolicy": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "name",
          "settings",
          "revision",
          "updated_at"
        ],
        "properties": {
          "id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128,
            "pattern": "^[^\\u0000]*$"
          },
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 64,
            "pattern": "^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$"
          },
          "settings": {
            "$ref": "#/components/schemas/ActionsPolicySettings"
          },
          "revision": {
            "type": "integer",
            "minimum": 1
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "ActionsPolicySettings": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "profile": {
            "type": "string",
            "enum": [
              "linux-basic",
              "full"
            ],
            "default": "linux-basic",
            "description": "Stored preference only; the runner label selects the image tier at admission. `full` is admitted only where its image and route are verified and the workspace's allowed_profiles covers it."
          },
          "preferences": {
            "$ref": "#/components/schemas/ProviderPreferences",
            "description": "Soft provider order, exclusions, sort and fallback permission, shared with sandbox creation. They narrow and never add supply, accounts or authority."
          },
          "allowed_providers": {
            "type": "array",
            "uniqueItems": true,
            "minItems": 1,
            "items": {
              "type": "string",
              "minLength": 1,
              "maxLength": 64,
              "pattern": "^[a-z][a-z0-9-]*$"
            },
            "description": "Optional allowlist that can only narrow workspace-approved routes."
          },
          "allowed_regions": {
            "type": "array",
            "uniqueItems": true,
            "minItems": 1,
            "items": {
              "type": "string",
              "minLength": 1,
              "maxLength": 128,
              "pattern": "^[^\\u0000]*$"
            },
            "description": "Reserved until Actions can verify each placement region. New non-null values are refused; a previously saved region restriction keeps admission closed rather than selecting an unverified region."
          },
          "allowed_route_ids": {
            "type": "array",
            "uniqueItems": true,
            "minItems": 1,
            "items": {
              "type": "string",
              "minLength": 1,
              "maxLength": 128,
              "pattern": "^[^\\u0000]*$"
            },
            "description": "Optional list of exact route IDs owned by this workspace. It can only narrow workspace-approved routes; the IDs are validated against current workspace routes at admission."
          },
          "max_runtime_seconds": {
            "type": "integer",
            "minimum": 1,
            "maximum": 1800,
            "description": "Maximum runtime after GitHub actually assigns a job; pickup allowance is separate."
          },
          "max_customer_charge_usd": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^(0|[1-9][0-9]*)(\\.[0-9]+)?$",
            "description": "Optional exact US-dollar cap; null removes this policy's cap but does not widen workspace guardrails."
          }
        }
      },
      "CreateActionsPolicy": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "name",
          "settings"
        ],
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 64,
            "pattern": "^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$"
          },
          "settings": {
            "$ref": "#/components/schemas/ActionsPolicySettings"
          }
        }
      },
      "UpdateActionsPolicy": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "name",
          "settings"
        ],
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 64,
            "pattern": "^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$"
          },
          "settings": {
            "$ref": "#/components/schemas/ActionsPolicySettings"
          }
        }
      },
      "ActionsPreviewRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "repository_id"
        ],
        "properties": {
          "repository_id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128,
            "pattern": "^[^\\u0000]*$"
          },
          "label": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128,
            "default": "boxrouter-ubuntu-24.04",
            "description": "One BoxRouter runner label; absent means the catalog's default Ubuntu 24.04 runner."
          },
          "policy_id": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "maxLength": 128,
            "pattern": "^[^\\u0000]*$"
          }
        }
      },
      "ActionsPreviewResult": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "repository_id",
          "label",
          "status",
          "eligible_routes",
          "exclusions",
          "reason"
        ],
        "properties": {
          "repository_id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128,
            "pattern": "^[^\\u0000]*$"
          },
          "label": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128
          },
          "status": {
            "type": "string",
            "enum": [
              "eligible",
              "refused",
              "unknown"
            ]
          },
          "eligible_routes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ActionsPreviewRoute"
            }
          },
          "exclusions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ActionsPreviewExclusion"
            }
          },
          "reason": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "maxLength": 1024
          }
        }
      },
      "ActionsPreviewRoute": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "provider",
          "region"
        ],
        "properties": {
          "provider": {
            "type": "string",
            "minLength": 1,
            "maxLength": 64,
            "pattern": "^[a-z][a-z0-9-]*$"
          },
          "region": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "maxLength": 128
          }
        }
      },
      "ActionsPreviewExclusion": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "provider",
          "code",
          "reason"
        ],
        "properties": {
          "provider": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "maxLength": 64,
            "pattern": "^[a-z][a-z0-9-]*$"
          },
          "code": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128,
            "description": "Stable refusal category; clients must preserve future values."
          },
          "reason": {
            "type": "string",
            "minLength": 1,
            "maxLength": 1024
          }
        }
      },
      "ActionsRunFilterText": {
        "type": "string",
        "minLength": 1,
        "maxLength": 513,
        "pattern": "^[^\\u0000]*$"
      },
      "ActionsRunStateFilter": {
        "description": "A run state, or the result status of an ended run.",
        "type": "string",
        "enum": [
          "queued",
          "preparing",
          "starting",
          "running",
          "stopping",
          "ended",
          "attention_required",
          "succeeded",
          "failed",
          "cancelled",
          "skipped",
          "neutral"
        ]
      },
      "ActionsRunFilterValues": {
        "type": "array",
        "minItems": 1,
        "maxItems": 50,
        "uniqueItems": true,
        "items": {
          "$ref": "#/components/schemas/ActionsRunFilterText"
        }
      },
      "ActionsRunPage": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "data",
          "next_cursor"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ActionsRun"
            }
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "maxLength": 128,
            "pattern": "^[^\\u0000]*$"
          },
          "counts": {
            "$ref": "#/components/schemas/ActionsRunCounts",
            "description": "Workspace-wide tab counts, independent of the query's filters."
          },
          "total": {
            "type": "integer",
            "minimum": 0,
            "description": "Number of runs matching this query's filters, across all pages."
          }
        }
      },
      "ActionsRun": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "github_run_id",
          "run_attempt",
          "repository_id",
          "workflow_name",
          "state",
          "result",
          "created_at",
          "updated_at",
          "billing"
        ],
        "properties": {
          "id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128,
            "pattern": "^[^\\u0000]*$"
          },
          "github_run_id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128,
            "pattern": "^[^\\u0000]*$"
          },
          "run_attempt": {
            "type": "integer",
            "minimum": 1
          },
          "repository_id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128,
            "pattern": "^[^\\u0000]*$"
          },
          "repository": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255,
            "description": "Durable GitHub repository full name when known."
          },
          "workflow_name": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "maxLength": 255
          },
          "workflow": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255,
            "description": "GitHub workflow name when known."
          },
          "branch": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255,
            "description": "Head branch when known."
          },
          "run_url": {
            "type": "string",
            "format": "uri",
            "maxLength": 2048,
            "description": "GitHub workflow run URL when known."
          },
          "head_branch": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "maxLength": 255
          },
          "head_sha": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128,
            "pattern": "^[^\\u0000]*$"
          },
          "run_number": {
            "type": "integer",
            "minimum": 1
          },
          "display_title": {
            "type": "string",
            "minLength": 1
          },
          "actor": {
            "$ref": "#/components/schemas/ActionsGitHubActor",
            "description": "Original actor GitHub recorded for the workflow run. Absent when unknown."
          },
          "triggering_actor": {
            "$ref": "#/components/schemas/ActionsGitHubActor",
            "description": "Actor who triggered the current run attempt",
            "separately recorded by GitHub. Absent when unknown.": null
          },
          "state": {
            "$ref": "#/components/schemas/ActionsRunState"
          },
          "result": {
            "$ref": "#/components/schemas/ActionsWorkResult"
          },
          "failure": {
            "$ref": "#/components/schemas/ActionsFailure"
          },
          "waiting": {
            "$ref": "#/components/schemas/ActionsRunWaiting"
          },
          "sources": {
            "type": "object",
            "additionalProperties": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          },
          "providers": {
            "type": "array",
            "uniqueItems": true,
            "items": {
              "type": "string",
              "minLength": 1,
              "maxLength": 64,
              "pattern": "^[a-z][a-z0-9-]*$"
            },
            "description": "Provider IDs that ran this run's jobs, distinct, in job order. Absent when no job has been placed."
          },
          "started_at": {
            "type": "string",
            "format": "date-time",
            "description": "When the first job of this run started. Absent until one has."
          },
          "completed_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When the last job of this run ended. Null while the run is active; absent when the run ended and no end time was confirmed."
          },
          "billing": {
            "$ref": "#/components/schemas/ActionsBilling"
          },
          "controls": {
            "$ref": "#/components/schemas/ActionsRunControls",
            "description": "Optional caller-specific workflow controls for this exact attempt. Mutation routes recheck authorization and the live GitHub attempt."
          },
          "cost": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/ActionsCost"
              },
              {
                "type": "null"
              }
            ],
            "description": "Sum of job costs. Null when one or more job costs are unknown; pending with a null amount when at least one job has no amount yet. Never presents a partial sum as the run total."
          }
        }
      },
      "ActionsGitHubActor": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "login",
          "profile_url"
        ],
        "properties": {
          "login": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255,
            "pattern": "^[^\\u0000]*$"
          },
          "profile_url": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri",
            "maxLength": 2048,
            "pattern": "^https://github\\.com/(apps/)?[^/?#]+$",
            "description": "The actor's GitHub profile, or https://github.com/apps/<slug> for a GitHub App bot."
          }
        }
      },
      "ActionsRunState": {
        "type": "string",
        "enum": [
          "queued",
          "preparing",
          "starting",
          "running",
          "stopping",
          "ended",
          "attention_required"
        ]
      },
      "ActionsWorkResult": {
        "type": [
          "string",
          "null"
        ],
        "enum": [
          "success",
          "workload_failure",
          "cancelled",
          "timed_out",
          "infrastructure_failure",
          "skipped",
          "neutral",
          "unknown",
          null
        ]
      },
      "ActionsFailure": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "kind",
          "reason_code",
          "message",
          "link_target"
        ],
        "properties": {
          "kind": {
            "type": "string",
            "enum": [
              "workflow",
              "boxrouter"
            ]
          },
          "reason_code": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 128,
            "pattern": "^[a-z][a-z0-9_.-]{0,127}$"
          },
          "message": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "maxLength": 1024
          },
          "link_target": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "byok",
              "credits",
              "github",
              null
            ]
          }
        }
      },
      "ActionsRunWaiting": {
        "type": "object",
        "additionalProperties": false,
        "description": "The longest-waiting job of a run that has jobs waiting. Absent when none waits and from servers that predate it.",
        "required": [
          "job_count",
          "reason_code",
          "since"
        ],
        "properties": {
          "job_count": {
            "type": "integer",
            "minimum": 1
          },
          "reason_code": {
            "type": "string",
            "minLength": 1,
            "maxLength": 64,
            "pattern": "^[a-z][a-z0-9_]{0,63}$"
          },
          "since": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "ActionsBilling": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "provider_cost",
          "customer_charge"
        ],
        "properties": {
          "provider_cost": {
            "description": "Existing sandbox provider-cost projection; null means no cost evidence is available.",
            "oneOf": [
              {
                "$ref": "#/components/schemas/SandboxCostSummary"
              },
              {
                "$ref": "#/components/schemas/Cost"
              },
              {
                "type": "null"
              }
            ]
          },
          "customer_charge": {
            "$ref": "#/components/schemas/ActionsCharge"
          }
        }
      },
      "SandboxCostSummary": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "label",
          "total"
        ],
        "description": "The label and total of a sandbox's cost, as list rows carry them. Both are the full cost's:\nsee the `cost` schema for what they mean. Actions billing adds the cost's `summary`, the one\nsentence that says what the total is or why there is none; list rows do not carry it.\n",
        "properties": {
          "label": {
            "$ref": "#/components/schemas/CostLabel"
          },
          "total": {
            "$ref": "#/components/schemas/CostTotal"
          },
          "summary": {
            "$ref": "#/components/schemas/summary"
          }
        },
        "if": {
          "properties": {
            "label": {
              "const": "unknown"
            }
          },
          "required": [
            "label"
          ]
        },
        "then": {
          "properties": {
            "total": {
              "type": "null"
            }
          }
        },
        "else": {
          "properties": {
            "total": {
              "type": "object"
            }
          }
        }
      },
      "CostLabel": {
        "description": "reported: a provider amount verified at list price; calculated: provider usage priced at stored list rates; unknown: required provider evidence or a rate is missing.",
        "enum": [
          "reported",
          "calculated",
          "unknown"
        ]
      },
      "CostTotal": {
        "description": "An exact USD amount, low equal to high, or null for unknown.",
        "anyOf": [
          {
            "$ref": "#/components/schemas/CostTotalRange"
          },
          {
            "type": "null"
          }
        ]
      },
      "CostTotalRange": {
        "description": "Exact USD total: low equals high.",
        "type": "object",
        "additionalProperties": false,
        "required": [
          "low",
          "high"
        ],
        "properties": {
          "low": {
            "$ref": "#/components/schemas/PricingDecimal"
          },
          "high": {
            "$ref": "#/components/schemas/PricingDecimal"
          }
        }
      },
      "PricingDecimal": {
        "description": "A non-negative decimal number as a string, in plain notation without an exponent.",
        "type": "string",
        "pattern": "^(0|[1-9][0-9]*)(\\.[0-9]+)?$"
      },
      "summary": {
        "description": "The total as one sentence, or why there is none. The sentences of `lines[].text` add up to it.",
        "type": "string",
        "minLength": 1
      },
      "Cost": {
        "title": "Cost",
        "description": "A provider-sourced sandbox cost. Unknown has a null total; known totals are exact decimal strings. Hourly rate-card quotes may be ranges.",
        "type": "object",
        "additionalProperties": false,
        "required": [
          "label",
          "total",
          "lines",
          "held_back_by",
          "exclusions",
          "price_version",
          "as_of"
        ],
        "properties": {
          "label": {
            "description": "reported: a provider amount verified at list price; calculated: provider usage priced at stored list rates; unknown: required provider evidence or a rate is missing.",
            "enum": [
              "reported",
              "calculated",
              "unknown"
            ]
          },
          "total": {
            "description": "An exact USD amount, low equal to high, or null for unknown.",
            "anyOf": [
              {
                "$ref": "#/components/schemas/CostTotalRange"
              },
              {
                "type": "null"
              }
            ]
          },
          "lines": {
            "description": "The working: one line per charged resource. Empty when the provider's own figure is all we have, or when nothing could be worked out.",
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "what",
                "quantity",
                "unit",
                "rate",
                "amount",
                "quantity_source"
              ],
              "properties": {
                "what": {
                  "enum": [
                    "cpu",
                    "memory",
                    "disk",
                    "gpu",
                    "machine",
                    "creation",
                    "egress",
                    "snapshot_storage"
                  ]
                },
                "quantity": {
                  "$ref": "#/components/schemas/PricingDecimal"
                },
                "unit": {
                  "description": "The price version's unit for this rate, for example vcpu-second.",
                  "type": "string",
                  "minLength": 1
                },
                "rate": {
                  "description": "US dollars per unit, as the price version states it.",
                  "$ref": "#/components/schemas/PricingDecimal"
                },
                "amount": {
                  "$ref": "#/components/schemas/PricingDecimal"
                },
                "quantity_source": {
                  "description": "The source of the usage facts the quantity came from; the least certain one when it came from several.",
                  "$ref": "#/components/schemas/CostSource"
                },
                "text": {
                  "description": "The line as a sentence a person reads, with its numbers: the quantity, the rate and the amount.",
                  "type": "string",
                  "minLength": 1
                },
                "sources": {
                  "description": "Where each number of the line came from, as words: the quantity, the rate and the amount.",
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "amount"
                  ],
                  "properties": {
                    "quantity": {
                      "type": "string",
                      "minLength": 1
                    },
                    "rate": {
                      "type": "string",
                      "minLength": 1
                    },
                    "amount": {
                      "type": "string",
                      "minLength": 1
                    }
                  }
                }
              }
            }
          },
          "held_back_by": {
            "description": "Reasons in plain words. Shared pricing findings are projected to their text for the HTTP response.",
            "type": "array",
            "items": {
              "type": "string",
              "minLength": 1
            }
          },
          "exclusions": {
            "description": "What the figure leaves out, such as plan fees, credits and discounts.",
            "type": "array",
            "items": {
              "type": "string",
              "minLength": 1
            }
          },
          "price_version": {
            "description": "The id of the price version used, which carries the quotes. Null when none was in effect.",
            "type": [
              "string",
              "null"
            ],
            "pattern": "^[a-z][a-z0-9-]*@[0-9]{4}-[0-9]{2}-[0-9]{2}(?:-([01][0-9]|2[0-3])[0-5][0-9][0-5][0-9]Z)?$"
          },
          "as_of": {
            "description": "When Cloud calculated or recorded the cost. A sandbox that has not ended has no cost yet.",
            "$ref": "#/components/schemas/PricingTimestamp"
          },
          "per_hour": {
            "description": "US dollars per hour for an ended sandbox; no hourly cost is returned while it is running.",
            "$ref": "#/components/schemas/CostMoneyRange"
          },
          "reported_figure": {
            "description": "Where a `reported` total came from. Present exactly when the label is `reported`.",
            "type": "object",
            "additionalProperties": false,
            "required": [
              "source",
              "observed_at",
              "how"
            ],
            "properties": {
              "source": {
                "$ref": "#/components/schemas/CostSource",
                "const": "provider"
              },
              "observed_at": {
                "$ref": "#/components/schemas/PricingTimestamp"
              },
              "how": {
                "description": "The API call that returned the figure.",
                "type": "string",
                "minLength": 1
              }
            }
          },
          "summary": {
            "description": "The total as one sentence, or why there is none. The sentences of `lines[].text` add up to it.",
            "type": "string",
            "minLength": 1
          }
        },
        "allOf": [
          {
            "if": {
              "properties": {
                "label": {
                  "const": "unknown"
                }
              },
              "required": [
                "label"
              ]
            },
            "then": {
              "properties": {
                "total": {
                  "type": "null"
                }
              }
            },
            "else": {
              "properties": {
                "total": {
                  "type": "object"
                }
              }
            }
          },
          {
            "if": {
              "properties": {
                "label": {
                  "const": "reported"
                }
              },
              "required": [
                "label"
              ]
            },
            "then": {
              "required": [
                "reported_figure"
              ]
            },
            "else": {
              "not": {
                "required": [
                  "reported_figure"
                ]
              }
            }
          }
        ]
      },
      "CostSource": {
        "description": "Where a fact came from. The same six values as the usage record's source; a test keeps the two lists equal.",
        "type": "string",
        "enum": [
          "provider",
          "published",
          "measured",
          "recorded",
          "calculated",
          "unknown"
        ]
      },
      "PricingTimestamp": {
        "description": "A UTC time, ending in Z.",
        "type": "string",
        "format": "date-time",
        "pattern": "^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9](\\.[0-9]+)?Z$"
      },
      "CostMoneyRange": {
        "description": "US dollars as a range; low equals high when the amount is exact.",
        "$ref": "#/components/schemas/CostDecimalRange"
      },
      "CostDecimalRange": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "low",
          "high"
        ],
        "properties": {
          "low": {
            "$ref": "#/components/schemas/PricingDecimal"
          },
          "high": {
            "$ref": "#/components/schemas/PricingDecimal"
          }
        }
      },
      "ActionsCharge": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "state",
          "held",
          "final"
        ],
        "properties": {
          "state": {
            "type": "string",
            "enum": [
              "pending",
              "final",
              "unknown"
            ]
          },
          "held": {
            "description": "Credits held for this charge from the funding quote, if any; a hold, not an incurred provider cost or a final charge.",
            "oneOf": [
              {
                "$ref": "#/components/schemas/ActionsMoney"
              },
              {
                "type": "null"
              }
            ]
          },
          "final": {
            "description": "Final BoxRouter customer charge. Managed charges require settlement in the existing ledger; BYOK compute has an explicit zero charge because the connected provider bills the customer directly. Null while pending or unknown.",
            "oneOf": [
              {
                "$ref": "#/components/schemas/ActionsMoney"
              },
              {
                "type": "null"
              }
            ]
          },
          "reason": {
            "type": [
              "string",
              "null"
            ],
            "x-boxrouter-open-enum": true,
            "enum": [
              "byok_no_charge",
              "held_not_final",
              "evidence_unavailable",
              "aggregate_unavailable",
              null
            ],
            "description": "Optional bounded explanation from the charge evidence already available to this read. It does not report settlement processing, retry or delay state."
          }
        },
        "allOf": [
          {
            "if": {
              "properties": {
                "state": {
                  "const": "final"
                }
              },
              "required": [
                "state"
              ]
            },
            "then": {
              "properties": {
                "final": {
                  "$ref": "#/components/schemas/ActionsMoney"
                }
              }
            },
            "else": {
              "properties": {
                "final": {
                  "type": "null"
                }
              }
            }
          },
          {
            "if": {
              "properties": {
                "state": {
                  "const": "unknown"
                }
              },
              "required": [
                "state"
              ]
            },
            "then": {
              "properties": {
                "held": {
                  "type": "null"
                },
                "final": {
                  "type": "null"
                }
              }
            }
          }
        ]
      },
      "ActionsMoney": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "currency",
          "amount"
        ],
        "properties": {
          "currency": {
            "type": "string",
            "const": "usd"
          },
          "amount": {
            "type": "string",
            "minLength": 1,
            "pattern": "^(0|[1-9][0-9]*)(\\.[0-9]+)?$",
            "description": "Exact non-negative US-dollar amount in plain decimal notation."
          }
        }
      },
      "ActionsRunControls": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "cancel",
          "rerun"
        ],
        "properties": {
          "cancel": {
            "$ref": "#/components/schemas/ActionsRunControl"
          },
          "rerun": {
            "$ref": "#/components/schemas/ActionsRunControl"
          },
          "rerun_failed_jobs": {
            "$ref": "#/components/schemas/ActionsRunControl",
            "description": "Whether the failed jobs of this attempt and jobs that depend on them may be rerun. Passed jobs may rerun when they depend on a failed job. Absent from servers that predate the control."
          }
        }
      },
      "ActionsRunControl": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "allowed"
        ],
        "properties": {
          "allowed": {
            "type": "boolean",
            "description": "Whether this caller may perform this control on the current run attempt."
          },
          "reason_code": {
            "type": "string",
            "enum": [
              "not_authorized",
              "already_finished",
              "not_current_attempt",
              "not_finished",
              "github_unavailable",
              "no_failed_jobs"
            ],
            "description": "Optional reason when allowed is false; omitted when the reason is not known."
          }
        }
      },
      "ActionsCost": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "amount",
          "currency",
          "status",
          "basis",
          "evidence"
        ],
        "properties": {
          "amount": {
            "description": "Exact amount in currency, as a plain decimal string. Null while a cost is pending; unknown cost is represented by a null cost object, never by zero.",
            "oneOf": [
              {
                "type": "string",
                "pattern": "^(0|[1-9][0-9]*)(\\.[0-9]+)?$"
              },
              {
                "type": "null"
              }
            ]
          },
          "currency": {
            "type": "string",
            "const": "USD"
          },
          "status": {
            "type": "string",
            "enum": [
              "final",
              "pending"
            ],
            "description": "Legacy provider cost. final requires the provider's own cost or usage records; pending has no amount. Estimated costs are unavailable and represented by a null cost object. Prefer billing.provider_cost."
          },
          "basis": {
            "type": "string",
            "enum": [
              "provider_reported",
              "calculated"
            ],
            "description": "Whether the amount came from provider-reported cost or from usage multiplied by a pinned price version."
          },
          "per_hour": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^(0|[1-9][0-9]*)(\\.[0-9]+)?$",
            "description": "Optional current USD-per-hour rate when all contributing sandboxes share one known rate; null when unavailable or mixed."
          },
          "evidence": {
            "type": "array",
            "minItems": 1,
            "description": "One source entry per distinct Actions sandbox included in the job or run total. Run evidence is the deduplicated union of its jobs' evidence.",
            "items": {
              "$ref": "#/components/schemas/ActionsCostEvidence"
            }
          }
        },
        "allOf": [
          {
            "if": {
              "properties": {
                "status": {
                  "const": "pending"
                }
              },
              "required": [
                "status"
              ]
            },
            "then": {
              "properties": {
                "amount": {
                  "type": "null"
                }
              }
            },
            "else": {
              "properties": {
                "amount": {
                  "type": "string",
                  "pattern": "^(0|[1-9][0-9]*)(\\.[0-9]+)?$"
                }
              }
            }
          },
          {
            "if": {
              "properties": {
                "status": {
                  "const": "final"
                }
              },
              "required": [
                "status"
              ]
            },
            "then": {
              "properties": {
                "evidence": {
                  "items": {
                    "properties": {
                      "ended_at": {
                        "type": "string",
                        "format": "date-time"
                      },
                      "usage_source": {
                        "const": "provider"
                      }
                    }
                  }
                }
              }
            }
          },
          {
            "if": {
              "properties": {
                "basis": {
                  "const": "calculated"
                },
                "amount": {
                  "type": "string"
                }
              },
              "required": [
                "basis",
                "amount"
              ]
            },
            "then": {
              "properties": {
                "evidence": {
                  "items": {
                    "properties": {
                      "price_version": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            }
          }
        ]
      },
      "ActionsCostEvidence": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "sandbox_id",
          "usage_source",
          "price_version",
          "started_at",
          "ended_at"
        ],
        "properties": {
          "sandbox_id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128,
            "pattern": "^[^\\u0000]*$"
          },
          "usage_source": {
            "$ref": "#/components/schemas/CostSource"
          },
          "price_version": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "maxLength": 128,
            "description": "Price version used for calculated cost, null when this evidence has no applicable price version."
          },
          "started_at": {
            "type": "string",
            "format": "date-time",
            "description": "Start of this Actions sandbox's billable lifetime, from its durable lifetime record."
          },
          "ended_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "Time destroy was confirmed; null while the Actions sandbox lifetime is still open or cleanup is unconfirmed."
          }
        }
      },
      "ActionsRunCounts": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "live",
          "all"
        ],
        "properties": {
          "live": {
            "type": "integer",
            "minimum": 0,
            "description": "Runs in progress: their state is queued, preparing, starting or running."
          },
          "all": {
            "type": "integer",
            "minimum": 0,
            "description": "All runs in the workspace."
          }
        }
      },
      "ActionsRunFacets": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "state",
          "repository",
          "workflow",
          "triggered_by",
          "branch",
          "job",
          "runner_label"
        ],
        "properties": {
          "state": {
            "$ref": "#/components/schemas/ActionsRunFacetList"
          },
          "repository": {
            "$ref": "#/components/schemas/ActionsRunFacetList",
            "description": "Values are repository IDs, for `repository_id`."
          },
          "workflow": {
            "$ref": "#/components/schemas/ActionsRunFacetList"
          },
          "triggered_by": {
            "$ref": "#/components/schemas/ActionsRunFacetList"
          },
          "branch": {
            "$ref": "#/components/schemas/ActionsRunFacetList"
          },
          "job": {
            "$ref": "#/components/schemas/ActionsRunFacetList",
            "description": "Values are unpadded base64url-encoded UTF-8 JSON `[workflow, job]`; labels are `Workflow › job`."
          },
          "runner_label": {
            "$ref": "#/components/schemas/ActionsRunFacetList"
          }
        }
      },
      "ActionsRunFacetList": {
        "type": "array",
        "items": {
          "$ref": "#/components/schemas/ActionsRunFacetValue"
        }
      },
      "ActionsRunFacetValue": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "value",
          "label",
          "count"
        ],
        "properties": {
          "value": {
            "type": "string",
            "minLength": 1,
            "maxLength": 513,
            "description": "What to send as the filter's parameter."
          },
          "label": {
            "type": "string",
            "minLength": 1,
            "maxLength": 256
          },
          "count": {
            "type": "integer",
            "minimum": 0,
            "description": "Runs in the workspace that have this value."
          }
        }
      },
      "ActionsPoolIdleTimeReport": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "since",
          "until",
          "runner_count",
          "idle_seconds",
          "billing",
          "pools"
        ],
        "properties": {
          "since": {
            "type": "string",
            "format": "date-time",
            "description": "The start of the range read, inclusive."
          },
          "until": {
            "type": "string",
            "format": "date-time",
            "description": "The end of the range read, exclusive."
          },
          "runner_count": {
            "type": "integer",
            "minimum": 0,
            "description": "Runners that started in the range and served no job."
          },
          "idle_seconds": {
            "type": "integer",
            "minimum": 0,
            "description": "Total lifetime of those runners."
          },
          "billing": {
            "description": "Provider cost and customer charge of all those runners together; the charge is final only when every runner's charge is.",
            "$ref": "#/components/schemas/ActionsBilling"
          },
          "pools": {
            "type": "array",
            "maxItems": 1000,
            "items": {
              "$ref": "#/components/schemas/ActionsPoolIdleTimePool"
            }
          }
        }
      },
      "ActionsPoolIdleTimePool": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "pool_id",
          "labels",
          "runner_count",
          "idle_seconds",
          "billing"
        ],
        "properties": {
          "pool_id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128,
            "pattern": "^[^\\u0000]*$",
            "description": "Opaque ID of the runner pool; it is the same for every runner with the same repository and labels."
          },
          "labels": {
            "type": "array",
            "maxItems": 64,
            "items": {
              "type": "string",
              "minLength": 1,
              "maxLength": 128,
              "pattern": "^[^\\u0000]*$"
            },
            "description": "The runner labels that define the pool."
          },
          "runner_count": {
            "type": "integer",
            "minimum": 0,
            "description": "Runners of this pool that started in the range and served no job."
          },
          "idle_seconds": {
            "type": "integer",
            "minimum": 0
          },
          "billing": {
            "$ref": "#/components/schemas/ActionsBilling"
          }
        }
      },
      "ActionsJobPage": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "data",
          "next_cursor"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ActionsJob"
            }
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "maxLength": 128,
            "pattern": "^[^\\u0000]*$"
          }
        }
      },
      "ActionsJob": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "run_id",
          "github_job_id",
          "name",
          "state",
          "result",
          "placement_ids"
        ],
        "properties": {
          "id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128,
            "pattern": "^[^\\u0000]*$"
          },
          "run_id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128,
            "pattern": "^[^\\u0000]*$"
          },
          "github_job_id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128,
            "pattern": "^[^\\u0000]*$"
          },
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255
          },
          "repository": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255,
            "description": "Durable GitHub repository full name when known."
          },
          "workflow": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255,
            "description": "GitHub workflow name when known."
          },
          "job_name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255,
            "description": "GitHub job name when known."
          },
          "job_url": {
            "type": "string",
            "format": "uri",
            "maxLength": 2048,
            "description": "GitHub workflow job URL when known."
          },
          "run_url": {
            "type": "string",
            "format": "uri",
            "maxLength": 2048,
            "description": "GitHub workflow run URL when known."
          },
          "branch": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255,
            "description": "Head branch when known."
          },
          "head_sha": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128,
            "pattern": "^[^\\u0000]*$"
          },
          "requested_environment": {
            "$ref": "#/components/schemas/ActionsRequestedEnvironment"
          },
          "requested_labels": {
            "type": [
              "array",
              "null"
            ],
            "description": "GitHub runner labels frozen from the verified workflow job request at admission; absent or null when historical evidence is unavailable.",
            "items": {
              "type": "string",
              "minLength": 1,
              "maxLength": 128,
              "pattern": "^[^\\u0000]*$"
            }
          },
          "state": {
            "$ref": "#/components/schemas/ActionsRunState"
          },
          "result": {
            "$ref": "#/components/schemas/ActionsWorkResult"
          },
          "failure": {
            "$ref": "#/components/schemas/ActionsFailure"
          },
          "waiting": {
            "$ref": "#/components/schemas/ActionsWaiting"
          },
          "machine": {
            "$ref": "#/components/schemas/ActionsMachine"
          },
          "billing": {
            "$ref": "#/components/schemas/ActionsBilling"
          },
          "cost": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/ActionsCost"
              },
              {
                "type": "null"
              }
            ],
            "description": "Cost for this job, summed across its distinct Actions sandboxes. Null when no trustworthy cost evidence is available."
          },
          "lifetime_seconds": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1
          },
          "sources": {
            "type": "object",
            "additionalProperties": true,
            "properties": {
              "region": {
                "$ref": "#/components/schemas/ActionsRegionSource"
              }
            }
          },
          "sandbox": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/ActionsJobSandbox"
              },
              {
                "type": "null"
              }
            ],
            "description": "The most recent durable placement sandbox for this job, including after cleanup."
          },
          "placement_ids": {
            "type": "array",
            "uniqueItems": true,
            "items": {
              "type": "string",
              "minLength": 1,
              "maxLength": 128,
              "pattern": "^[^\\u0000]*$"
            }
          },
          "route_selection": {
            "$ref": "#/components/schemas/ActionsRouteSelection"
          },
          "creation": {
            "$ref": "#/components/schemas/CreationDiagnostics",
            "description": "Diagnostics of the latest placement's creation; each placement carries its own."
          },
          "ordered_routes": {
            "type": "array",
            "description": "Frozen route facts in the same order as route_selection.ordered_route_ids.",
            "items": {
              "$ref": "#/components/schemas/ActionsOrderedRoute"
            }
          }
        }
      },
      "ActionsRequestedEnvironment": {
        "type": "object",
        "additionalProperties": false,
        "description": "Frozen admitted job request values only, from jobs.request_json metadata.actions.policy.profile and requirements. These are requested values, not configured or observed allocation. Null means the value was not recorded or is invalid; no defaults or current policy are inferred.",
        "required": [
          "profile",
          "cpu",
          "memory_mib",
          "disk_mib"
        ],
        "properties": {
          "profile": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "linux-basic",
              "linux-docker",
              "full",
              null
            ],
            "x-boxrouter-open-enum": true,
            "description": "Frozen at request time; jobs written before the label simplification may still read linux-docker."
          },
          "cpu": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1
          },
          "memory_mib": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1
          },
          "disk_mib": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1
          }
        }
      },
      "ActionsWaiting": {
        "type": "object",
        "additionalProperties": false,
        "description": "Why a job that has not started is still waiting. A `running` job can also wait, while its registered runner waits for GitHub to hand it the job (reason_code `registered`); its run reads `starting` unless another of its jobs is further along. Present only while it waits; absent otherwise and from servers that predate it. `sources.waiting` names the record it came from.",
        "required": [
          "reason_code",
          "since"
        ],
        "properties": {
          "reason_code": {
            "type": "string",
            "minLength": 1,
            "maxLength": 64,
            "pattern": "^[a-z][a-z0-9_]{0,63}$",
            "description": "Bounded wait code, for example no_eligible_routes, insufficient_credit, compatible_slot_occupied, provider_capacity or admitted. Unknown codes are possible; clients show a generic waiting sentence."
          },
          "since": {
            "type": "string",
            "format": "date-time",
            "description": "When the job began waiting for this reason."
          },
          "action": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "settings",
              "credits",
              "byok",
              "github",
              null
            ],
            "x-boxrouter-open-enum": true,
            "description": "Where the customer can resolve the wait, when they can."
          },
          "required_nanodollars": {
            "type": "string",
            "maxLength": 19,
            "pattern": "^(0|[1-9][0-9]{0,18})$",
            "description": "What the job needs from the workspace's available credit, in billionths of a US dollar, the same figure the create refusal `insufficient_credit` reports. Present only for the reason_code `insufficient_credit`, and absent when Cloud did not record it."
          },
          "available_nanodollars": {
            "type": "string",
            "maxLength": 19,
            "pattern": "^(0|[1-9][0-9]{0,18})$",
            "description": "What the workspace had available when the job was refused, never below zero. Present only with `required_nanodollars`."
          }
        },
        "dependentRequired": {
          "available_nanodollars": [
            "required_nanodollars"
          ]
        }
      },
      "ActionsMachine": {
        "type": "object",
        "additionalProperties": false,
        "description": "What machine the job ran on and how fast it was against what is usual. Absent while the job has no recorded machine facts and from servers that predate it. `typical_score` and `speed_ratio` are null unless enough signed samples from enough workspaces stand behind the typical score.",
        "required": [
          "integrity"
        ],
        "properties": {
          "cpu_model": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 96,
            "description": "The CPU model the guest reported, as the provider shows it."
          },
          "effective_cpus": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1,
            "description": "CPUs the job could use."
          },
          "score": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1,
            "description": "CPU score of this machine, per CPU."
          },
          "integrity": {
            "type": "string",
            "enum": [
              "signed",
              "unsigned"
            ],
            "x-boxrouter-open-enum": true,
            "description": "signed when the guest proved the record with the job capability; only signed records are compared."
          },
          "steal_ratio": {
            "type": [
              "number",
              "null"
            ],
            "minimum": 0,
            "maximum": 1,
            "description": "Share of CPU time the provider host took away during the job, when the guest can tell."
          },
          "typical_score": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1,
            "description": "Typical 7-day score per CPU for this provider, size and label."
          },
          "speed_ratio": {
            "type": [
              "number",
              "null"
            ],
            "exclusiveMinimum": 0,
            "description": "typical_score divided by score; above 1 means this machine was slower than usual."
          },
          "memory_mib": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1,
            "description": "Memory the machine reported: the cgroup limit when present, else the virtual machine total. Omitted when the provider does not report a trustworthy value. `facts.memory.basis` names which."
          },
          "disk_write_mbps": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0,
            "description": "Disk write speed in MB/s, measured by BoxRouter. `facts.disk` says whether it was measured on this job or on another machine of the same route."
          },
          "disk_read_mbps": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0,
            "description": "Disk read speed in MB/s, measured by BoxRouter. `facts.disk` says whether it was measured on this job or on another machine of the same route."
          },
          "facts": {
            "$ref": "#/components/schemas/ActionsMachineFacts",
            "description": "Where each shown machine value came from, one entry per value present. Omitted from servers that predate it."
          }
        }
      },
      "ActionsMachineFacts": {
        "type": "object",
        "additionalProperties": false,
        "description": "One source per shown machine value. A key is omitted when its value is.",
        "properties": {
          "cpu": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "kind"
            ],
            "properties": {
              "kind": {
                "type": "string",
                "enum": [
                  "job_start",
                  "job_after_steps"
                ],
                "x-boxrouter-open-enum": true,
                "description": "job_start: read before the job steps ran. job_after_steps: an unsigned record read after the steps could run."
              }
            }
          },
          "memory": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "kind",
              "basis"
            ],
            "properties": {
              "kind": {
                "type": "string",
                "enum": [
                  "job_start",
                  "job_after_steps"
                ],
                "x-boxrouter-open-enum": true
              },
              "basis": {
                "type": "string",
                "enum": [
                  "cgroup_limit",
                  "vm_total"
                ],
                "x-boxrouter-open-enum": true,
                "description": "cgroup_limit: the memory limit the machine reported. vm_total: the total memory the machine reported."
              }
            }
          },
          "disk": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "kind"
            ],
            "properties": {
              "kind": {
                "type": "string",
                "enum": [
                  "job_start",
                  "job_after_steps",
                  "image_check"
                ],
                "x-boxrouter-open-enum": true,
                "description": "image_check: measured on another machine of the same route when BoxRouter last checked the runner image; this job's machine was not measured."
              },
              "observed_at": {
                "type": "string",
                "format": "date-time",
                "description": "When an image_check was measured. Present only for image_check."
              }
            }
          }
        }
      },
      "ActionsRegionSource": {
        "type": "object",
        "additionalProperties": true,
        "description": "Where the region value came from. Other keys name the record read; they stay open.",
        "properties": {
          "kind": {
            "type": "string",
            "enum": [
              "provider_reported",
              "account_setting",
              "route_setting",
              "provider_docs"
            ],
            "x-boxrouter-open-enum": true,
            "description": "provider_reported: the provider API reported it for this sandbox. account_setting: set on the provider account. route_setting: set on the route. provider_docs: the provider documents it as the default."
          },
          "url": {
            "type": "string",
            "format": "uri",
            "maxLength": 2048,
            "description": "The documentation page, for provider_docs."
          },
          "read_at": {
            "type": "string",
            "format": "date",
            "description": "Day the page was read, for provider_docs."
          }
        }
      },
      "ActionsJobSandbox": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "state",
          "removed_at"
        ],
        "properties": {
          "id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128,
            "pattern": "^[^\\u0000]*$"
          },
          "state": {
            "type": "string",
            "enum": [
              "creating",
              "running",
              "paused",
              "stopped",
              "destroying",
              "destroyed",
              "error",
              "unknown"
            ],
            "x-boxrouter-open-enum": true
          },
          "removed_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "Time cleanup was confirmed; null until the sandbox's removal is confirmed."
          }
        }
      },
      "ActionsRouteSelection": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "objective",
          "ordered_route_ids",
          "selected_route_id",
          "reason",
          "basis",
          "considered",
          "list_price_usd_per_hour",
          "ready_ms_p50",
          "readiness_scope",
          "fallback"
        ],
        "properties": {
          "objective": {
            "type": "string",
            "enum": [
              "default",
              "fastest",
              "cheapest"
            ],
            "x-boxrouter-choices": {
              "default": {
                "label": "Workspace setting",
                "line": "Uses the workspace routing setting."
              },
              "fastest": {
                "label": "Fastest",
                "line": "Shortest run time measured on reference workloads first.",
                "measure": "time",
                "better": "lower"
              },
              "cheapest": {
                "label": "Cheapest",
                "line": "Lowest hourly price first.",
                "measure": "price",
                "better": "lower"
              }
            }
          },
          "ordered_route_ids": {
            "type": "array",
            "minItems": 1,
            "uniqueItems": true,
            "items": {
              "type": "string",
              "minLength": 1,
              "maxLength": 128,
              "pattern": "^[^\\u0000]*$"
            }
          },
          "selected_route_id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128,
            "pattern": "^[^\\u0000]*$"
          },
          "reason": {
            "type": "string",
            "minLength": 1,
            "maxLength": 256
          },
          "basis": {
            "type": "string",
            "enum": [
              "observed",
              "static"
            ]
          },
          "considered": {
            "type": "integer",
            "minimum": 1
          },
          "list_price_usd_per_hour": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "pattern": "^(0|[1-9][0-9]*)(\\.[0-9]+)?$"
          },
          "ready_ms_p50": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0
          },
          "readiness_scope": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "route",
              "provider_region",
              "provider",
              "none",
              null
            ]
          },
          "fallback": {
            "type": "boolean",
            "description": "Ranking marker with its released meaning unchanged. It does not name provider attempts or fallback permission; see `fallbacks_allowed` and `stopped_reason`."
          },
          "routed_away": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "provider",
              "size_cpu",
              "signal",
              "window_minutes"
            ],
            "description": "Present only when health demotion changes the selected route in Automatic or Fastest workspace mode for a Run with the applicable non-price `default` or `fastest` objective. Absent for legacy runs, when routing is off or shadow-only, and for Cheapest or Custom objectives.",
            "properties": {
              "provider": {
                "type": "string",
                "minLength": 1,
                "maxLength": 64,
                "pattern": "^[a-z][a-z0-9-]*$",
                "description": "Public provider id of the route that would have ranked first without the health signal. Uses the same vocabulary and bound as ActionsOrderedRoute.provider."
              },
              "size_cpu": {
                "type": "integer",
                "minimum": 1,
                "description": "CPU count of the job shape that was routed away; shapes without a CPU count do not produce this object."
              },
              "signal": {
                "type": "string",
                "enum": [
                  "slow_machines",
                  "slow_starts"
                ],
                "x-boxrouter-open-enum": true,
                "description": "slow_machines maps to a 60-minute window; slow_starts maps to a 15-minute window."
              },
              "window_minutes": {
                "type": "integer",
                "minimum": 1,
                "description": "60 for slow_machines or 15 for slow_starts."
              }
            },
            "allOf": [
              {
                "if": {
                  "properties": {
                    "signal": {
                      "const": "slow_machines"
                    }
                  }
                },
                "then": {
                  "properties": {
                    "window_minutes": {
                      "const": 60
                    }
                  }
                }
              },
              {
                "if": {
                  "properties": {
                    "signal": {
                      "const": "slow_starts"
                    }
                  }
                },
                "then": {
                  "properties": {
                    "window_minutes": {
                      "const": 15
                    }
                  }
                }
              }
            ]
          },
          "fallbacks_allowed": {
            "type": "boolean",
            "description": "The effective allow_fallbacks for creating this placement; absent before this field existed."
          },
          "stopped_reason": {
            "$ref": "#/components/schemas/CreationStoppedReason"
          },
          "funding_group": {
            "$ref": "#/components/schemas/FundingGroup",
            "description": "Frozen payer group; absent on older responses. Definite pre-create refusal retries only later frozen candidates in this same group."
          },
          "workspace_mode": {
            "type": "string",
            "enum": [
              "automatic",
              "cheapest",
              "fastest",
              "custom"
            ],
            "x-boxrouter-open-enum": true,
            "x-boxrouter-choices": {
              "automatic": {
                "label": "Auto",
                "line": "A random draw weighted toward lower hourly price."
              },
              "cheapest": {
                "label": "Cheapest",
                "line": "Lowest hourly price first.",
                "measure": "price",
                "better": "lower"
              },
              "fastest": {
                "label": "Fastest",
                "line": "Shortest run time measured on reference workloads first.",
                "measure": "time",
                "better": "lower"
              },
              "custom": {
                "label": "Custom",
                "line": "Your exact provider order, top to bottom."
              }
            },
            "description": "Effective workspace mode at admission; absent on older responses."
          }
        }
      },
      "CreationStoppedReason": {
        "type": [
          "string",
          "null"
        ],
        "enum": [
          "fallbacks_disabled",
          "no_eligible_route",
          "uncertain_outcome",
          "authority_changed",
          "deadline_reached",
          "cancelled",
          null
        ],
        "x-boxrouter-open-enum": true,
        "description": "Why creation stopped dispatching further routes: `fallbacks_disabled` (allow_fallbacks was\nfalse and the one permitted dispatch was refused), `no_eligible_route` (every remaining\nroute was excluded), `uncertain_outcome` (a dispatch may have allocated; never retried, reconcile\nwith the operation), `authority_changed` (account, funding or privacy authority no longer\npermits the next route), `deadline_reached` and `cancelled`. Null when a route created the\nsandbox. Clients must tolerate values they do not know.\n"
      },
      "FundingGroup": {
        "type": "string",
        "enum": [
          "prioritized",
          "credits",
          "fallback"
        ],
        "x-boxrouter-open-enum": true,
        "description": "The frozen payer group; no cross-group retry after a dispatch refusal at launch."
      },
      "CreationDiagnostics": {
        "type": "object",
        "additionalProperties": false,
        "description": "Bounded public diagnostics of one creation: the effective fallback permission, why\ndispatching stopped, the ordered dispatched attempts (the successful one included) and,\nseparately, the routes skipped before dispatch. All fields are optional and absent when\nunknown. Each list holds at most 64 entries and is always an ordered prefix of the full\nlist. When entries were omitted, the matching `*_truncated` flag is true and the `*_total`\ncount gives the full length, so omitted candidates are never read as not dispatched.\nThe confirmed binding is reported separately on the sandbox or placement. Prior-refusal\nlists elsewhere keep their meaning.\n",
        "properties": {
          "fallbacks_allowed": {
            "type": "boolean",
            "description": "The effective allow_fallbacks after inheritance."
          },
          "stopped_reason": {
            "$ref": "#/components/schemas/CreationStoppedReason"
          },
          "attempts": {
            "type": "array",
            "maxItems": 64,
            "items": {
              "$ref": "#/components/schemas/CreationDiagnosticAttempt"
            }
          },
          "attempts_truncated": {
            "type": "boolean",
            "description": "True when attempts holds only a prefix of the dispatched attempts."
          },
          "attempts_total": {
            "type": "integer",
            "minimum": 0,
            "description": "Full number of dispatched attempts; required when attempts_truncated is true."
          },
          "preparation_skips": {
            "type": "array",
            "maxItems": 64,
            "items": {
              "$ref": "#/components/schemas/CreationDiagnosticSkip"
            }
          },
          "preparation_skips_truncated": {
            "type": "boolean",
            "description": "True when preparation_skips holds only a prefix."
          },
          "preparation_skips_total": {
            "type": "integer",
            "minimum": 0,
            "description": "Full number of skipped routes; required when preparation_skips_truncated is true."
          }
        },
        "allOf": [
          {
            "if": {
              "properties": {
                "attempts_truncated": {
                  "const": true
                }
              },
              "required": [
                "attempts_truncated"
              ]
            },
            "then": {
              "required": [
                "attempts_total"
              ]
            }
          },
          {
            "if": {
              "properties": {
                "preparation_skips_truncated": {
                  "const": true
                }
              },
              "required": [
                "preparation_skips_truncated"
              ]
            },
            "then": {
              "required": [
                "preparation_skips_total"
              ]
            }
          }
        ]
      },
      "CreationDiagnosticAttempt": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "provider",
          "outcome",
          "native_code",
          "native_status"
        ],
        "description": "A dispatched attempt in CreationDiagnostics, with the same meaning as CreationAttempt and\nbounded scalars. The operation readback keeps its unbounded legacy items.\n",
        "properties": {
          "provider": {
            "type": "string",
            "minLength": 1,
            "maxLength": 64
          },
          "outcome": {
            "type": "string",
            "enum": [
              "completed",
              "not_started",
              "unknown",
              "partial"
            ],
            "x-boxrouter-open-enum": true,
            "description": "Clients must tolerate values they do not know."
          },
          "native_code": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 128
          },
          "native_status": {
            "type": [
              "integer",
              "null"
            ]
          },
          "route_id": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 128
          },
          "account_id": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 128
          },
          "supply": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 32
          },
          "cause": {
            "$ref": "#/components/schemas/CreationRouteCause"
          }
        },
        "allOf": [
          {
            "if": {
              "properties": {
                "outcome": {
                  "not": {
                    "const": "not_started"
                  }
                }
              },
              "required": [
                "outcome"
              ]
            },
            "then": {
              "properties": {
                "native_code": {
                  "type": "null"
                },
                "native_status": {
                  "type": "null"
                }
              }
            }
          }
        ]
      },
      "CreationRouteCause": {
        "type": "string",
        "minLength": 1,
        "maxLength": 64,
        "enum": [
          "key_rejected",
          "plan_unbuildable",
          "privacy_denied",
          "not_ready",
          "not_dispatched",
          "provider_create_failed"
        ],
        "x-boxrouter-open-enum": true,
        "description": "Why one route did not create the sandbox, in a bounded word: `key_rejected` (the provider\nrefused the saved key), `plan_unbuildable` (the route matched but its create could not be\nbuilt), `privacy_denied` (the workspace's privacy settings refused the route),\n`not_ready` (the route's provider session was not ready in time), `not_dispatched`\n(refused locally before any provider call) and `provider_create_failed` (the provider was\nasked and the create failed). Clients must tolerate values they do not know.\n"
      },
      "CreationDiagnosticSkip": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "provider",
          "reason_code"
        ],
        "description": "A route skipped locally before any provider dispatch, with bounded scalars. It is not an attempt.",
        "properties": {
          "provider": {
            "type": "string",
            "minLength": 1,
            "maxLength": 64
          },
          "route_id": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 128
          },
          "account_id": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 128
          },
          "reason_code": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128
          },
          "cause": {
            "$ref": "#/components/schemas/CreationRouteCause"
          }
        }
      },
      "ActionsOrderedRoute": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "route_id",
          "provider",
          "provider_label",
          "region"
        ],
        "properties": {
          "route_id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128,
            "pattern": "^[^\\u0000]*$"
          },
          "provider": {
            "type": "string",
            "minLength": 1,
            "maxLength": 64,
            "pattern": "^[a-z][a-z0-9-]*$"
          },
          "provider_label": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128
          },
          "region": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "maxLength": 128
          }
        }
      },
      "ActionsPlacementPage": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "data",
          "next_cursor"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ActionsPlacement"
            }
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "maxLength": 128,
            "pattern": "^[^\\u0000]*$"
          }
        }
      },
      "ActionsPlacement": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "run_id",
          "job_id",
          "requested_job_id",
          "assigned_job_id",
          "provider",
          "sandbox_id",
          "state",
          "result",
          "cleanup_state",
          "started_at",
          "ended_at",
          "billing",
          "created_at",
          "updated_at"
        ],
        "properties": {
          "id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128,
            "pattern": "^[^\\u0000]*$"
          },
          "run_id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128,
            "pattern": "^[^\\u0000]*$"
          },
          "job_id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128,
            "pattern": "^[^\\u0000]*$"
          },
          "requested_job_id": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "maxLength": 128,
            "pattern": "^[^\\u0000]*$"
          },
          "assigned_job_id": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "maxLength": 128,
            "pattern": "^[^\\u0000]*$"
          },
          "route_id": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "maxLength": 128,
            "pattern": "^[^\\u0000]*$",
            "description": "The route whose provider actually created this placement's sandbox. Explicit null means no actual allocation is bound yet (creation is unconfirmed); it is never an admission-selected placeholder. Bound placements carry the nonempty route ID unchanged."
          },
          "provider": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "maxLength": 64,
            "pattern": "^[a-z][a-z0-9-]*$"
          },
          "sandbox_id": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "maxLength": 128,
            "pattern": "^[^\\u0000]*$"
          },
          "sandbox_link": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "maxLength": 2048,
            "pattern": "^/(?!/)[^\\u0000]*$",
            "description": "Optional same-origin Sandboxes page path."
          },
          "region": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "maxLength": 128
          },
          "size": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/ActionsMachineSize"
              },
              {
                "type": "null"
              }
            ]
          },
          "supply": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "byok",
              "managed",
              null
            ]
          },
          "sources": {
            "type": "object",
            "additionalProperties": true,
            "properties": {
              "region": {
                "$ref": "#/components/schemas/ActionsRegionSource"
              }
            }
          },
          "state": {
            "$ref": "#/components/schemas/ActionsRunState"
          },
          "result": {
            "$ref": "#/components/schemas/ActionsWorkResult"
          },
          "cleanup_state": {
            "$ref": "#/components/schemas/ActionsCleanupState"
          },
          "started_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "ended_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "billing": {
            "$ref": "#/components/schemas/ActionsBilling"
          },
          "creation": {
            "$ref": "#/components/schemas/CreationDiagnostics"
          },
          "lifetime_seconds": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "ActionsCleanupState": {
        "type": "string",
        "enum": [
          "pending",
          "confirmed",
          "unknown"
        ]
      },
      "ActionsJobSteps": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "job_id",
          "run_id",
          "github_job_id",
          "run_attempt",
          "availability",
          "steps",
          "observed_at",
          "source"
        ],
        "properties": {
          "job_id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128,
            "pattern": "^[^\\u0000]*$"
          },
          "run_id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128,
            "pattern": "^[^\\u0000]*$"
          },
          "github_job_id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128,
            "pattern": "^[^\\u0000]*$"
          },
          "run_attempt": {
            "type": "integer",
            "minimum": 1
          },
          "availability": {
            "type": "string",
            "enum": [
              "available",
              "pending",
              "unavailable",
              "forbidden",
              "removed"
            ]
          },
          "steps": {
            "type": "array",
            "maxItems": 1000,
            "items": {
              "$ref": "#/components/schemas/ActionsWorkflowStep"
            }
          },
          "observed_at": {
            "type": "string",
            "format": "date-time"
          },
          "source": {
            "type": "string",
            "enum": [
              "github_workflow_job"
            ]
          },
          "reason_code": {
            "type": "string",
            "minLength": 1,
            "maxLength": 64,
            "pattern": "^[a-z][a-z0-9_]{0,63}$"
          }
        }
      },
      "ActionsWorkflowStep": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "position",
          "number",
          "name",
          "status",
          "conclusion",
          "started_at",
          "completed_at"
        ],
        "properties": {
          "position": {
            "type": "integer",
            "minimum": 0
          },
          "number": {
            "type": "integer",
            "minimum": 1
          },
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255
          },
          "status": {
            "type": "string",
            "minLength": 1,
            "maxLength": 64
          },
          "conclusion": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 64
          },
          "started_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "completed_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        }
      },
      "ActionsJobLogs": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "job_id",
          "run_id",
          "github_job_id",
          "run_attempt",
          "observed_at",
          "source",
          "availability",
          "text",
          "byte_count",
          "partial"
        ],
        "properties": {
          "job_id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128,
            "pattern": "^[^\\u0000]*$"
          },
          "run_id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128,
            "pattern": "^[^\\u0000]*$"
          },
          "github_job_id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128,
            "pattern": "^[^\\u0000]*$"
          },
          "run_attempt": {
            "type": "integer",
            "minimum": 1
          },
          "observed_at": {
            "type": "string",
            "format": "date-time"
          },
          "source": {
            "type": "string",
            "enum": [
              "github_job_log",
              "github_step_log"
            ]
          },
          "availability": {
            "type": "string",
            "enum": [
              "available",
              "pending",
              "unavailable",
              "forbidden",
              "removed"
            ]
          },
          "text": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 1048576
          },
          "byte_count": {
            "type": "integer",
            "minimum": 0,
            "maximum": 1048576,
            "description": "Number of source log bytes fetched, before UTF-8 decoding. An incomplete trailing UTF-8 sequence is omitted from text; byte_count still includes those fetched bytes."
          },
          "partial": {
            "type": "boolean"
          },
          "step_position": {
            "type": "integer",
            "minimum": 0
          },
          "reason_code": {
            "type": "string",
            "minLength": 1,
            "maxLength": 64,
            "pattern": "^[a-z][a-z0-9_]{0,63}$"
          }
        },
        "allOf": [
          {
            "if": {
              "properties": {
                "availability": {
                  "const": "available"
                }
              },
              "required": [
                "availability"
              ]
            },
            "then": {
              "properties": {
                "text": {
                  "type": "string"
                }
              }
            }
          }
        ]
      },
      "ActionsJobEventPage": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "events",
          "next_cursor"
        ],
        "properties": {
          "events": {
            "type": "array",
            "maxItems": 1000,
            "items": {
              "$ref": "#/components/schemas/ActionsJobStepEvent"
            }
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "maxLength": 128,
            "pattern": "^[^\\u0000]*$"
          }
        }
      },
      "ActionsJobStepEvent": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "event_id",
          "ts",
          "step",
          "outcome",
          "reason_code",
          "duration_ms",
          "delivery_id",
          "workspace_id",
          "installation_id",
          "repository_id",
          "run_id",
          "run_attempt",
          "job_id",
          "demand_id",
          "route_id",
          "sandbox_id",
          "mutation_id",
          "request_id",
          "trace_id"
        ],
        "properties": {
          "event_id": {
            "type": "string",
            "format": "uuid"
          },
          "ts": {
            "type": "string",
            "format": "date-time"
          },
          "step": {
            "type": "string",
            "enum": [
              "webhook_received",
              "admission",
              "registration",
              "image_verification",
              "controller_pass",
              "sandbox_create",
              "launch",
              "assignment",
              "result",
              "cleanup"
            ]
          },
          "outcome": {
            "type": "string",
            "enum": [
              "ok",
              "refused",
              "ignored",
              "deferred",
              "unknown",
              "error"
            ]
          },
          "reason_code": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 64,
            "pattern": "^[a-z][a-z0-9_]{0,63}$"
          },
          "duration_ms": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0
          },
          "delivery_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "request_id": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "maxLength": 128,
            "pattern": "^[^\\u0000]*$"
          },
          "trace_id": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 32,
            "maxLength": 32,
            "pattern": "^[0-9a-f]{32}$"
          },
          "workspace_id": {
            "type": "string",
            "minLength": 1
          },
          "installation_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "repository_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "run_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "run_attempt": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0
          },
          "job_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "demand_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "route_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "sandbox_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "mutation_id": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "ActionsRunControlResult": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "operation_id",
          "run_id",
          "action",
          "scope",
          "outcome",
          "github_run_id",
          "run_attempt"
        ],
        "properties": {
          "operation_id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128,
            "pattern": "^[^\\u0000]*$"
          },
          "run_id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128,
            "pattern": "^[^\\u0000]*$"
          },
          "action": {
            "type": "string",
            "enum": [
              "cancel",
              "rerun",
              "rerun_failed_jobs"
            ]
          },
          "scope": {
            "type": "string",
            "const": "entire_workflow"
          },
          "outcome": {
            "type": "string",
            "enum": [
              "accepted",
              "unknown"
            ]
          },
          "github_run_id": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "maxLength": 128,
            "pattern": "^[^\\u0000]*$"
          },
          "run_attempt": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1
          }
        }
      },
      "Operation": {
        "type": "object",
        "description": "Durable record of a mutation's outcome and identifiers. Error detail is returned with the original response and correlated by request_id; it is not stored in this record. Creation operations may include a sanitized route and selection summary. These fields are absent for non-create operations. Attempts may name the public route, account and supply they dispatched; payer and child identifiers, provider messages and credentials are never exposed.",
        "required": [
          "id",
          "operation",
          "outcome",
          "observed_at",
          "sandbox_id"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "operation": {
            "type": "string",
            "description": "OpenAPI operation ID of the attempted mutation."
          },
          "outcome": {
            "type": "string",
            "enum": [
              "not_started",
              "completed",
              "partial",
              "unknown"
            ]
          },
          "observed_at": {
            "type": "string",
            "format": "date-time"
          },
          "sandbox_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Owned BoxRouter resource when established, including recovered creations."
          },
          "settled_by": {
            "type": "string",
            "enum": [
              "wait_timeout",
              "lifetime_elapsed"
            ],
            "x-boxrouter-open-enum": true,
            "description": "Present when BoxRouter settled the operation itself rather than observing its end. `wait_timeout`: a command's wait ran out, so `outcome` is `completed` for BoxRouter's request but the command may still be running at the provider. `lifetime_elapsed`: a create whose result BoxRouter could never read, closed once the provider's maximum sandbox lifetime had passed; `outcome` stays `unknown` because BoxRouter cannot tell whether a sandbox was made, but any sandbox it made has ended, and its cost is unknown. Clients must tolerate values they do not know; absence means the outcome was observed."
          },
          "native_resource_id": {
            "type": "string",
            "minLength": 1,
            "description": "Recorded opaque handle for the operation's provider-specific resource, when known. Use it only with the original sandbox and the matching native operation family. This identifier does not grant access or prove completion. Credentials are never stored in this field; absence means no handle was recorded."
          },
          "route": {
            "type": "object",
            "additionalProperties": false,
            "description": "Sanitized selected route for a create operation. Omitted for non-create operations. Contains no payer or child identifiers.",
            "required": [
              "provider",
              "account_id",
              "supply",
              "selection"
            ],
            "properties": {
              "provider": {
                "type": "string",
                "minLength": 1
              },
              "account_id": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "supply": {
                "type": "string",
                "minLength": 1
              },
              "selection": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "ranked_by",
                  "attempts",
                  "preparation_skips"
                ],
                "properties": {
                  "ranked_by": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "attempts": {
                    "type": "array",
                    "description": "Provider dispatch attempts in order. Native refusal evidence is present only for a durable definite refusal; unknown outcomes never carry refusal evidence.",
                    "items": {
                      "$ref": "#/components/schemas/CreationAttempt"
                    }
                  },
                  "preparation_skips": {
                    "type": "array",
                    "description": "Routes skipped locally before a provider dispatch.",
                    "items": {
                      "$ref": "#/components/schemas/CreationPreparationSkip"
                    }
                  },
                  "fallbacks_allowed": {
                    "type": "boolean",
                    "description": "The effective allow_fallbacks after inheritance."
                  },
                  "stopped_reason": {
                    "$ref": "#/components/schemas/CreationStoppedReason"
                  }
                }
              }
            }
          }
        },
        "allOf": [
          {
            "if": {
              "properties": {
                "operation": {
                  "not": {
                    "const": "createSandbox"
                  }
                }
              },
              "required": [
                "operation"
              ]
            },
            "then": {
              "not": {
                "required": [
                  "route"
                ]
              }
            }
          }
        ]
      },
      "CreationAttempt": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "provider",
          "outcome",
          "native_code",
          "native_status"
        ],
        "description": "One provider dispatch made while creating, in dispatch order, including the one that\ncreated the sandbox. `outcome` is the operation vocabulary: completed, not_started\n(a definite refusal before any allocation), unknown and partial. Native refusal\nevidence is present only for a durable definite refusal. The route, account and supply\nname what was dispatched, not a confirmed binding, which is reported separately on the\nsandbox or placement. Payer, child and native payload identifiers are never returned.\n",
        "properties": {
          "provider": {
            "type": "string",
            "minLength": 1
          },
          "outcome": {
            "type": "string",
            "enum": [
              "completed",
              "not_started",
              "unknown",
              "partial"
            ]
          },
          "native_code": {
            "type": [
              "string",
              "null"
            ]
          },
          "native_status": {
            "type": [
              "integer",
              "null"
            ]
          },
          "route_id": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 128,
            "description": "The route this dispatch used."
          },
          "account_id": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 128,
            "description": "The connected account this dispatch used."
          },
          "supply": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 32,
            "description": "The funding authority of this dispatch: byok or managed."
          },
          "cause": {
            "$ref": "#/components/schemas/CreationRouteCause"
          }
        },
        "allOf": [
          {
            "if": {
              "properties": {
                "outcome": {
                  "enum": [
                    "completed",
                    "unknown",
                    "partial"
                  ]
                }
              },
              "required": [
                "outcome"
              ]
            },
            "then": {
              "properties": {
                "native_code": {
                  "type": "null"
                },
                "native_status": {
                  "type": "null"
                }
              }
            }
          }
        ]
      },
      "CreationPreparationSkip": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "provider",
          "reason_code"
        ],
        "description": "A route skipped locally before any provider dispatch. It is not an attempt.",
        "properties": {
          "provider": {
            "type": "string",
            "minLength": 1
          },
          "route_id": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 128,
            "description": "The route that was skipped."
          },
          "account_id": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 128,
            "description": "The connected account of the skipped route."
          },
          "reason_code": {
            "type": "string",
            "minLength": 1
          },
          "cause": {
            "$ref": "#/components/schemas/CreationRouteCause"
          }
        }
      },
      "Artifact": {
        "type": "object",
        "required": [
          "id",
          "size_bytes",
          "sha256",
          "expires_at"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "size_bytes": {
            "type": "integer",
            "minimum": 0
          },
          "sha256": {
            "type": "string",
            "pattern": "^[a-f0-9]{64}$"
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "description": "Staging retention deadline. This is not a persistent volume or checkpointed volume data."
          }
        }
      },
      "PrepareImage": {
        "type": "object",
        "additionalProperties": false,
        "description": "Two forms; send exactly one. `{image, providers, sizes?}` prepares on the named\nproviders. `{match, top?}` takes the body you send to POST /sandboxes or\nPOST /sandboxes/match: Cloud ranks routes exactly as that create would now, under this\nworkspace's payer rules, and prepares `match.image` on the first `top` distinct\nproviders, at `match.resources`. Fields that do not choose a route, such as env and\nlabels, are ignored. Ranking can change later, for example when prices or measured\nstart times change, so a later create may pick a provider that was not prepared.\n",
        "properties": {
          "image": {
            "description": "Image to prepare. Only with `providers`. A string is an OCI image reference. Use\n{private_oci} for an image whose registry needs a login, together with\n`registry_credentials`; it is prepared only on routes that use your own provider keys.\nA Dockerfile object uses the same source text and optional uploaded context artifact\nas a sandbox create. Only offerings declaring that prepared source and context mode\nare selected. The whole JSON request is limited to 64 KiB.\n",
            "oneOf": [
              {
                "type": "string",
                "minLength": 1,
                "not": {
                  "const": "provider_default"
                }
              },
              {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "private_oci"
                ],
                "properties": {
                  "private_oci": {
                    "type": "string",
                    "minLength": 1,
                    "description": "OCI image reference in a registry that needs a login."
                  }
                }
              },
              {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "dockerfile"
                ],
                "properties": {
                  "dockerfile": {
                    "type": "string",
                    "minLength": 1,
                    "pattern": "^[^\\u0000]*$",
                    "description": "Dockerfile source text. No inline context files or context URLs."
                  },
                  "context_artifact_id": {
                    "type": "string",
                    "minLength": 1,
                    "description": "Optional unexpired artifact owned by this workspace. Its tar context is\nleased through background preparation. Existing upload limits apply:\n10 MiB archive, 64 MiB expanded regular files and 2,048 entries.\n"
                  }
                }
              }
            ]
          },
          "registry_credentials": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "username",
              "password"
            ],
            "properties": {
              "username": {
                "type": "string",
                "minLength": 1,
                "pattern": "^[^\\u0000]*$"
              },
              "password": {
                "type": "string",
                "minLength": 1,
                "writeOnly": true,
                "pattern": "^[^\\u0000]*$"
              }
            },
            "description": "Request-only login for a private_oci `image`; required with it and refused without it.\nWith `match`, send it inside the match body instead. Both strings are non-empty, at\nmost 64 KiB UTF-8 bytes together. It is passed to the provider to set up the copy and\nis never stored, logged, traced or returned.\n"
          },
          "providers": {
            "$ref": "#/components/schemas/ImageProviders"
          },
          "sizes": {
            "type": "array",
            "minItems": 1,
            "uniqueItems": true,
            "items": {
              "type": "integer",
              "minimum": 1
            },
            "description": "Optional memory sizes to prepare, expressed in GiB. Only with `providers`."
          },
          "match": {
            "allOf": [
              {
                "$ref": "#/components/schemas/MatchSandbox"
              }
            ],
            "description": "A sandbox create body. Its `image` is an OCI reference or Dockerfile build object,\noptionally with context_artifact_id. A missing image, provider_default, an existing\nprovider artifact has nothing to prepare and is refused. Only\ndeclared prepared source/context variants are eligible. A private_oci image is\nprepared with the body's registry_credentials, only on routes that use your own\nprovider keys.\n"
          },
          "top": {
            "type": "integer",
            "minimum": 1,
            "default": 1,
            "description": "With `match`, how many of the best-ranked distinct providers to prepare on. Fewer\nare prepared when fewer providers can run the create.\n"
          }
        },
        "allOf": [
          {
            "oneOf": [
              {
                "required": [
                  "providers"
                ]
              },
              {
                "required": [
                  "match"
                ]
              }
            ]
          },
          {
            "if": {
              "required": [
                "providers"
              ]
            },
            "then": {
              "required": [
                "image"
              ]
            }
          },
          {
            "if": {
              "required": [
                "image"
              ]
            },
            "then": {
              "required": [
                "providers"
              ]
            }
          },
          {
            "if": {
              "required": [
                "sizes"
              ]
            },
            "then": {
              "required": [
                "providers"
              ]
            }
          },
          {
            "if": {
              "required": [
                "registry_credentials"
              ]
            },
            "then": {
              "required": [
                "providers"
              ]
            }
          },
          {
            "if": {
              "required": [
                "top"
              ]
            },
            "then": {
              "required": [
                "match"
              ]
            }
          }
        ]
      },
      "ImageProviders": {
        "description": "Provider names or all providers configured for this workspace.",
        "oneOf": [
          {
            "type": "array",
            "minItems": 1,
            "uniqueItems": true,
            "items": {
              "type": "string",
              "minLength": 1
            }
          },
          {
            "type": "string",
            "const": "all"
          }
        ]
      },
      "MatchSandbox": {
        "allOf": [
          {
            "$ref": "#/components/schemas/CreateSandbox"
          },
          {
            "not": {
              "type": "object",
              "properties": {
                "secret_values": {}
              },
              "required": [
                "secret_values"
              ]
            }
          }
        ],
        "description": "The creation request shape without request-only secret values. registry_credentials\nis accepted, as on create, so a private_oci body can be sent unchanged to match.\n"
      },
      "CreateSandbox": {
        "type": "object",
        "additionalProperties": false,
        "description": "A creation body: gates by name in requirements, a lifetime budget in lifetime_seconds,\nand a volume checkpoint to restore. Every field is optional; {} is a baseline sandbox in\nthe standard image that may run for 300 seconds, or for as long as the credit balance\ncovers it on a credit-funded route that can extend a lifetime. The words of the retired 0.2.0\nrequest (timeout_seconds, egress, provider, a dotted requirements key) are refused\nwith invalid_request, whose fix names the word to send instead. Creation controls are\nprovider-independent: use resources, lifetime_seconds, at_end, image, env, labels,\nrequirements and routing preferences. Provider-native creation options are not accepted.\n",
        "properties": {
          "lifetime_seconds": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 60,
            "description": "The sandbox's lifetime in seconds, starting when BoxRouter begins creation on the\nselected route. Creation time counts, so less time may remain when the sandbox is\nready. The minimum is 60 seconds. The requested value is matched against the route's\nmax_lifetime_seconds, and a credit-funded sandbox reserves credits for all of it.\n\nLeave it out for a credit-funded sandbox on a route that can extend a lifetime\n(`extendable_lifetime`) and the sandbox runs for as long as the workspace's credit\nbalance covers it: credits are reserved one hour at a time and renewed before each\nhour ends. `funded_until` on the sandbox says when the current reservation ends; the\nsandbox ends then if the balance could not cover another hour. Left out on any other\ncreate (a route that cannot extend a lifetime, or a sandbox paid with the workspace's\nown provider account), it is 300 seconds.\n\nNull asks for a sandbox with no lifetime: it runs until you destroy it. Only a provider\nthat never ends a sandbox serves it, and only on the workspace's own provider account;\nleave at_end out with it.\n"
          },
          "at_end": {
            "type": "string",
            "enum": [
              "destroy",
              "pause"
            ],
            "default": "destroy",
            "description": "What happens when the lifetime is used up. pause needs pause_resume in requirements.\nRefused with invalid_request when lifetime_seconds is null, because nothing ends that\nsandbox.\n"
          },
          "requirements": {
            "$ref": "#/components/schemas/SandboxProviderSpecRequirements",
            "x-boxrouter-sdk-list-shorthand": {}
          },
          "resources": {
            "$ref": "#/components/schemas/SandboxProviderSpecResources"
          },
          "preferences": {
            "$ref": "#/components/schemas/ProviderPreferences"
          },
          "privacy": {
            "$ref": "#/components/schemas/PrivacyPolicy"
          },
          "route": {
            "$ref": "#/components/schemas/CreationRouteFilter"
          },
          "volume": {
            "$ref": "#/components/schemas/AttachVolume"
          },
          "image": {
            "$ref": "#/components/schemas/SandboxImageSelection",
            "description": "Omitted selects BoxRouter's standard image. \"provider_default\" opts out and runs\nthe provider's own default. Any other string is an OCI image reference. Use a\none-key dockerfile or provider_artifact object for those artifact sources; the\nlatter requires exactly one value in preferences.only. Use {private_oci} for an image whose registry\nneeds a login, together with registry_credentials; it runs only on routes that use\nyour own provider keys. Every selected image must contain bash and\nsha256sum.\n"
          },
          "registry_credentials": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "username",
              "password"
            ],
            "properties": {
              "username": {
                "type": "string",
                "minLength": 1,
                "pattern": "^[^\\u0000]*$"
              },
              "password": {
                "type": "string",
                "minLength": 1,
                "writeOnly": true,
                "pattern": "^[^\\u0000]*$"
              }
            },
            "description": "Request-only login for the registry named by a private_oci image; required with it and\nrefused without it. Both strings are non-empty, at most 64 KiB UTF-8 bytes together\n(enforced outside JSON Schema). It is passed to the provider to set up a copy of the\nimage and is never stored, logged, traced, returned or included in idempotency records.\n"
          },
          "env": {
            "type": "object",
            "maxProperties": 256,
            "additionalProperties": {
              "type": "string"
            },
            "propertyNames": {
              "pattern": "^[A-Za-z_][A-Za-z0-9_]*$"
            },
            "description": "Creation-time environment, limited by the server to 64 KiB total UTF-8 bytes. This byte\nlimit is enforced outside JSON Schema validation. Never returned, logged or stored.\n"
          },
          "secret_refs": {
            "$ref": "#/components/schemas/AdditionalSecretReferences",
            "description": "Explicit saved workspace secret references by destination environment name."
          },
          "secret_values": {
            "type": "object",
            "minProperties": 1,
            "maxProperties": 256,
            "propertyNames": {
              "$ref": "#/components/schemas/SecretName"
            },
            "additionalProperties": {
              "type": "string",
              "writeOnly": true,
              "maxLength": 16384,
              "pattern": "^[^\\u0000]*$"
            },
            "description": "Request-only values delivered through the hidden_secrets gate. Values are sent once\nduring sandbox creation. The server enforces a 16 KiB per-value and 64 KiB total\nUTF-8 byte limit outside JSON Schema validation. Values are never stored, logged,\ntraced, returned, or included in idempotency records. Use the matching placeholder\nfrom the response in configuration.\n"
          },
          "labels": {
            "type": "object",
            "maxProperties": 64,
            "propertyNames": {
              "maxLength": 63
            },
            "additionalProperties": {
              "type": "string",
              "maxLength": 255
            },
            "description": "BoxRouter labels, returned on the sandbox; not implicitly provider tags."
          }
        },
        "allOf": [
          {
            "if": {
              "required": [
                "secret_values"
              ]
            },
            "then": {
              "required": [
                "requirements"
              ],
              "properties": {
                "requirements": {
                  "required": [
                    "hidden_secrets"
                  ]
                }
              }
            }
          },
          {
            "if": {
              "required": [
                "volume",
                "image"
              ]
            },
            "then": {
              "properties": {
                "image": {
                  "anyOf": [
                    {
                      "type": "string",
                      "allOf": [
                        {
                          "not": {
                            "const": "provider_default"
                          }
                        },
                        {
                          "not": {
                            "pattern": "^prepared:sha256:"
                          }
                        }
                      ]
                    },
                    {
                      "$ref": "#/components/schemas/SandboxImageSelectionProviderArtifact"
                    }
                  ]
                }
              }
            }
          },
          {
            "if": {
              "required": [
                "image"
              ],
              "properties": {
                "image": {
                  "type": "object",
                  "required": [
                    "provider_artifact"
                  ]
                }
              }
            },
            "then": {
              "required": [
                "preferences"
              ],
              "properties": {
                "preferences": {
                  "required": [
                    "only"
                  ],
                  "properties": {
                    "only": {
                      "maxItems": 1
                    }
                  }
                }
              }
            }
          }
        ]
      },
      "SandboxProviderSpecRequirements": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "custom_images": {
            "$ref": "#/components/schemas/SandboxProviderSpecCustomImagesRequirement"
          },
          "desktop": {
            "$ref": "#/components/schemas/SandboxProviderSpecDesktopRequirement"
          },
          "hidden_secrets": {
            "$ref": "#/components/schemas/SandboxProviderSpecHiddenSecretsRequirement"
          },
          "idle_shutdown": {
            "$ref": "#/components/schemas/SandboxProviderSpecIdleShutdownRequirement"
          },
          "network_lockdown": {
            "$ref": "#/components/schemas/SandboxProviderSpecNetworkLockdownRequirement"
          },
          "pause_resume": {
            "$ref": "#/components/schemas/SandboxProviderSpecPauseResumeRequirement"
          },
          "previews": {
            "$ref": "#/components/schemas/SandboxProviderSpecPreviewsRequirement"
          },
          "processes": {
            "$ref": "#/components/schemas/SandboxProviderSpecProcessesRequirement"
          },
          "tcp_ports": {
            "$ref": "#/components/schemas/SandboxProviderSpecTcpPortsRequirement"
          },
          "terminal": {
            "$ref": "#/components/schemas/SandboxProviderSpecTerminalRequirement"
          }
        },
        "if": {
          "required": [
            "previews"
          ],
          "properties": {
            "previews": {
              "required": [
                "survives_pause"
              ]
            }
          }
        },
        "then": {
          "anyOf": [
            {
              "required": [
                "pause_resume"
              ]
            },
            {
              "required": [
                "idle_shutdown"
              ]
            }
          ]
        },
        "x-boxrouter-sps-profile": {
          "version": 1,
          "requirements": {
            "custom_images": [],
            "desktop": [],
            "hidden_secrets": [
              "inject_into",
              "intercepts",
              "transparent"
            ],
            "idle_shutdown": [
              "custom_idle_time",
              "idle_seconds"
            ],
            "network_lockdown": [
              "allow",
              "deny",
              "policy"
            ],
            "pause_resume": [
              "keeps"
            ],
            "previews": [
              "access",
              "link_lifetime_seconds",
              "loopback",
              "ports",
              "revocable",
              "survives_pause",
              "websocket"
            ],
            "processes": [
              "input"
            ],
            "tcp_ports": [
              "ports",
              "tls"
            ],
            "terminal": []
          },
          "resources": [
            "arch",
            "cpu_min",
            "disk_min_mib",
            "extendable_lifetime",
            "kernel",
            "memory_min_mib",
            "paused_retention_seconds",
            "process_seconds",
            "region",
            "run_seconds"
          ]
        },
        "description": "The gates this sandbox may use, each holding its knobs and its settings side by side.\nA sandbox may use only the baseline and the gates named here: a call to any other gate\nis refused with not_named, on every adapter. Every gate the spec names is accepted\nhere, including the ones no adapter implements yet: whether one can be granted is\nmatching's answer, so a gate nothing declares, or no loaded report proves, leaves the\nrequest without a route rather than making it invalid.\n"
      },
      "SandboxProviderSpecCustomImagesRequirement": {
        "type": "object",
        "additionalProperties": false,
        "properties": {},
        "description": "Bring your own environment, which must contain bash and sha256sum.\n"
      },
      "SandboxProviderSpecDesktopRequirement": {
        "type": "object",
        "additionalProperties": false,
        "properties": {}
      },
      "SandboxProviderSpecHiddenSecretsRequirement": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "inject_into"
        ],
        "properties": {
          "transparent": {
            "type": "boolean"
          },
          "intercepts": {
            "oneOf": [
              {
                "enum": [
                  "injected_hosts",
                  "all_https"
                ]
              },
              {
                "type": "array",
                "minItems": 1,
                "uniqueItems": true,
                "items": {
                  "enum": [
                    "injected_hosts",
                    "all_https"
                  ]
                }
              }
            ]
          },
          "inject_into": {
            "type": "array",
            "minItems": 1,
            "uniqueItems": true,
            "items": {
              "$ref": "#/components/schemas/SandboxProviderSpecHostname"
            },
            "description": "Hostnames to which the credential is sent."
          }
        },
        "description": "Credentials the sandbox never sees: the adapter adds them to outgoing requests from\noutside it. The values travel like env and are never stored, logged or returned; the\nresponse shows their names only.\n"
      },
      "SandboxProviderSpecIdleShutdownRequirement": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "custom_idle_time": {
            "type": "boolean"
          },
          "idle_seconds": {
            "type": "integer",
            "minimum": 1,
            "description": "How long the sandbox must be inactive before idle shutdown."
          }
        },
        "allOf": [
          {
            "if": {
              "required": [
                "idle_seconds"
              ]
            },
            "then": {
              "properties": {
                "custom_idle_time": {
                  "const": true
                }
              }
            }
          },
          {
            "if": {
              "required": [
                "idle_seconds"
              ]
            },
            "then": {
              "required": [
                "custom_idle_time"
              ],
              "properties": {
                "custom_idle_time": {
                  "const": true
                }
              }
            }
          }
        ],
        "description": "End or pause a sandbox nobody is using. No knob must be named.\n"
      },
      "SandboxProviderSpecNetworkLockdownRequirement": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "policy"
        ],
        "properties": {
          "policy": {
            "enum": [
              "deny_all",
              "allowlist",
              "denylist",
              "open"
            ]
          },
          "allow": {
            "type": "array",
            "minItems": 1,
            "uniqueItems": true,
            "items": {
              "type": "string",
              "minLength": 1
            },
            "description": "Hosts or HTTP rules permitted by the selected network policy. Required for\nallowlist and forbidden with deny_all, denylist, or open.\n"
          },
          "deny": {
            "type": "array",
            "minItems": 1,
            "uniqueItems": true,
            "items": {
              "type": "string",
              "minLength": 1,
              "pattern": "^[^*]*$"
            }
          }
        },
        "allOf": [
          {
            "if": {
              "properties": {
                "policy": {
                  "const": "deny_all"
                }
              },
              "required": [
                "policy"
              ]
            },
            "then": {
              "not": {
                "anyOf": [
                  {
                    "required": [
                      "allow"
                    ]
                  },
                  {
                    "required": [
                      "deny"
                    ]
                  }
                ]
              }
            }
          },
          {
            "if": {
              "properties": {
                "policy": {
                  "const": "allowlist"
                }
              },
              "required": [
                "policy"
              ]
            },
            "then": {
              "required": [
                "allow"
              ],
              "not": {
                "required": [
                  "deny"
                ]
              }
            }
          },
          {
            "if": {
              "properties": {
                "policy": {
                  "const": "denylist"
                }
              },
              "required": [
                "policy"
              ]
            },
            "then": {
              "required": [
                "deny"
              ],
              "not": {
                "required": [
                  "allow"
                ]
              }
            }
          }
        ],
        "description": "Limits what the sandbox may connect to, enforced by the provider from outside it.\nPreviews still reach the sandbox. policy must be named and is exactly one value:\nan allowlist is not what someone assuming deny-all wants.\n"
      },
      "SandboxProviderSpecPauseResumeRequirement": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "keeps": {
            "oneOf": [
              {
                "enum": [
                  "files_only",
                  "files_and_memory"
                ]
              },
              {
                "type": "array",
                "minItems": 1,
                "uniqueItems": true,
                "items": {
                  "enum": [
                    "files_only",
                    "files_and_memory"
                  ]
                }
              }
            ],
            "description": "What a pause keeps. A list means any of these values is acceptable and the response\nsays which were granted; \"any\" is not accepted here, because keeps need not be named.\n"
          }
        },
        "description": "Pause a sandbox and resume it later. {} asks for the gate without naming a knob."
      },
      "SandboxProviderSpecPreviewsRequirement": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "access",
          "ports"
        ],
        "properties": {
          "access": {
            "oneOf": [
              {
                "enum": [
                  "any",
                  "public",
                  "private"
                ]
              },
              {
                "type": "array",
                "minItems": 1,
                "uniqueItems": true,
                "items": {
                  "enum": [
                    "public",
                    "private"
                  ]
                }
              }
            ],
            "description": "Which kinds of link this sandbox may open. \"any\" accepts whatever the route offers,\nand then the open call may not pick a kind.\n"
          },
          "revocable": {
            "type": "boolean"
          },
          "link_lifetime_seconds": {
            "type": "number",
            "exclusiveMinimum": 0
          },
          "websocket": {
            "type": "boolean"
          },
          "loopback": {
            "type": "boolean"
          },
          "survives_pause": {
            "type": "boolean"
          },
          "ports": {
            "type": "array",
            "minItems": 1,
            "uniqueItems": true,
            "items": {
              "type": "integer",
              "minimum": 1,
              "maximum": 65535
            },
            "description": "The ports previews may be opened on; more than max_ports excludes a route."
          }
        },
        "description": "A URL for a port inside the sandbox. access must be named, because some providers only\noffer public links; ports is the setting handed to the adapter and can exclude one.\n"
      },
      "SandboxProviderSpecProcessesRequirement": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "input": {
            "type": "boolean"
          }
        }
      },
      "SandboxProviderSpecTcpPortsRequirement": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "tls",
          "ports"
        ],
        "properties": {
          "tls": {
            "oneOf": [
              {
                "enum": [
                  "any",
                  "none"
                ]
              },
              {
                "type": "array",
                "minItems": 1,
                "uniqueItems": true,
                "items": {
                  "enum": [
                    "none"
                  ]
                }
              }
            ]
          },
          "ports": {
            "type": "array",
            "minItems": 1,
            "uniqueItems": true,
            "items": {
              "type": "integer",
              "minimum": 1,
              "maximum": 65535
            }
          }
        }
      },
      "SandboxProviderSpecTerminalRequirement": {
        "type": "object",
        "additionalProperties": false,
        "properties": {}
      },
      "SandboxImageSelection": {
        "oneOf": [
          {
            "type": "string",
            "const": "provider_default"
          },
          {
            "type": "string",
            "minLength": 1,
            "not": {
              "const": "provider_default"
            },
            "description": "OCI image reference."
          },
          {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "dockerfile"
            ],
            "properties": {
              "dockerfile": {
                "type": "string",
                "minLength": 1
              },
              "context_artifact_id": {
                "type": "string",
                "minLength": 1,
                "description": "Unexpired workspace-owned uploaded tar context, leased while the image builds."
              }
            }
          },
          {
            "$ref": "#/components/schemas/SandboxImageSelectionProviderArtifact"
          },
          {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "private_oci"
            ],
            "properties": {
              "private_oci": {
                "type": "string",
                "minLength": 1,
                "description": "OCI image reference in a registry that needs a login; send registry_credentials beside it."
              }
            }
          }
        ]
      },
      "SandboxImageSelectionProviderArtifact": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "provider_artifact"
        ],
        "properties": {
          "provider_artifact": {
            "type": "string",
            "minLength": 1,
            "description": "A provider-native artifact id usable on the selected provider account."
          }
        }
      },
      "ImagePreparationStatus": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "image",
          "providers"
        ],
        "properties": {
          "image": {
            "type": "string",
            "description": "Resolved OCI reference or the canonical sha256 content selector of a Dockerfile source and context."
          },
          "providers": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ImageProviderState"
            }
          }
        }
      },
      "ImageProviderState": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "provider",
          "size",
          "state",
          "reason"
        ],
        "properties": {
          "provider": {
            "type": "string",
            "minLength": 1,
            "description": "Installed provider selected through this workspace's authorized offerings."
          },
          "state": {
            "type": "string",
            "enum": [
              "queued",
              "preparing",
              "ready",
              "inactive",
              "deleting",
              "failed",
              "unsupported",
              "absent"
            ],
            "x-boxrouter-open-enum": true
          },
          "size": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1,
            "description": "Requested memory size in GiB, or null when the copy is not size-specific."
          },
          "reason": {
            "type": [
              "string",
              "null"
            ],
            "description": "Eligibility or preparation outcome for this provider."
          }
        }
      },
      "UnprepareImage": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "image",
          "providers"
        ],
        "properties": {
          "image": {
            "type": "string",
            "minLength": 1,
            "description": "Image reference, `repo@sha256:digest`, or the `sha256:<64 lowercase hex>` content\nselector returned for a Dockerfile build. A content selector reads this workspace's\nrecorded copies without contacting a registry. A private tag works when this workspace has\nprepared or created it with registry_credentials before; otherwise name its digest.\n"
          },
          "providers": {
            "$ref": "#/components/schemas/ImageProviders"
          }
        }
      },
      "StartProcess": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "command"
        ],
        "properties": {
          "command": {
            "x-boxrouter-input-error": "Command must not contain NUL bytes",
            "type": "string",
            "pattern": "^[^\\u0000]*$",
            "description": "Bash source run in a login shell."
          },
          "env": {
            "x-boxrouter-input-error": "Command env requires valid shell variable names and values without NUL",
            "type": [
              "object",
              "null"
            ],
            "propertyNames": {
              "pattern": "^[A-Za-z_][A-Za-z0-9_]*(?![\\s\\S])"
            },
            "additionalProperties": {
              "type": "string",
              "pattern": "^[^\\u0000]*$"
            },
            "description": "Environment overrides for the command."
          },
          "cwd": {
            "x-boxrouter-input-error": "Command cwd must be an absolute sandbox path without NUL bytes",
            "type": [
              "string",
              "null"
            ],
            "pattern": "^/[^\\u0000]*$",
            "description": "Absolute working directory within the sandbox."
          },
          "stdin": {
            "type": "boolean",
            "default": false,
            "description": "Keep stdin open for subsequent input requests. Requires named `processes.input`\nand selected-route `reattached_stdin` metadata; otherwise `stdin: true` is\nrefused as `unsupported_feature` before process launch.\n"
          },
          "wait_for_port": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1,
            "maximum": 65535,
            "description": "Return only after this port accepts TCP connections inside the sandbox, so the\ncaller needs no readiness loop. Waits at most 30 seconds. If the process exits first,\nor the port is still closed after the wait, the process is ended and the answer is\n409 `port_not_listening` with the output so far in `details`. Null returns as soon\nas the process starts.\n"
          }
        }
      },
      "Process": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id"
        ],
        "properties": {
          "id": {
            "type": "string",
            "minLength": 1
          }
        }
      },
      "ProcessOutput": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "stdout_base64",
          "stderr_base64",
          "next_stdout",
          "next_stderr",
          "exit_code"
        ],
        "properties": {
          "stdout_base64": {
            "type": "string",
            "contentEncoding": "base64"
          },
          "stderr_base64": {
            "type": "string",
            "contentEncoding": "base64"
          },
          "next_stdout": {
            "type": "integer",
            "minimum": 0
          },
          "next_stderr": {
            "type": "integer",
            "minimum": 0
          },
          "exit_code": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Set only after the process ended and both output streams were read to their ends."
          }
        }
      },
      "WriteStdin": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "data"
        ],
        "properties": {
          "data": {
            "type": "string",
            "description": "UTF-8 text to append exactly once; does not implicitly append a newline or send EOF."
          }
        }
      },
      "CreditBalance": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "mode",
          "currency",
          "settled_nanodollars",
          "held_nanodollars",
          "available_nanodollars",
          "purchase_bounds_minor"
        ],
        "properties": {
          "mode": {
            "type": "string",
            "enum": [
              "test",
              "live"
            ],
            "description": "Stripe environment configured for purchases; live mode remains disabled until accepted for real money."
          },
          "currency": {
            "type": "string",
            "const": "usd"
          },
          "settled_nanodollars": {
            "type": "string",
            "maxLength": 20,
            "pattern": "^(0|-?[1-9][0-9]{0,17}|-?[1-8][0-9]{18}|-?9[01][0-9]{17}|-?92[0-1][0-9]{16}|-?922[0-2][0-9]{15}|-?9223[0-2][0-9]{14}|-?92233[0-6][0-9]{13}|-?922337[0-1][0-9]{12}|-?92233720[0-2][0-9]{10}|-?922337203[0-5][0-9]{9}|-?9223372036[0-7][0-9]{8}|-?92233720368[0-4][0-9]{7}|-?922337203685[0-3][0-9]{6}|-?9223372036854[0-6][0-9]{5}|-?92233720368547[0-6][0-9]{4}|-?922337203685477[0-4][0-9]{3}|-?9223372036854775[0-7][0-9]{2}|922337203685477580[0-7]|-922337203685477580[0-8])$",
            "description": "Canonical base-10 signed 64-bit nanodollar amount as a string, preserving exact integer precision across JSON clients. Confirmed purchases and adjustments less settled usage, in billionths of a US dollar. Negative after a refund of spent credit."
          },
          "held_nanodollars": {
            "type": "string",
            "maxLength": 19,
            "pattern": "^(0|[1-9][0-9]{0,17}|[1-8][0-9]{18}|9[01][0-9]{17}|92[0-1][0-9]{16}|922[0-2][0-9]{15}|9223[0-2][0-9]{14}|92233[0-6][0-9]{13}|922337[0-1][0-9]{12}|92233720[0-2][0-9]{10}|922337203[0-5][0-9]{9}|9223372036[0-7][0-9]{8}|92233720368[0-4][0-9]{7}|922337203685[0-3][0-9]{6}|9223372036854[0-6][0-9]{5}|92233720368547[0-6][0-9]{4}|922337203685477[0-4][0-9]{3}|9223372036854775[0-7][0-9]{2}|922337203685477580[0-7])$",
            "description": "Canonical base-10 nonnegative 64-bit nanodollar amount as a string, preserving exact integer precision across JSON clients. Credit reserved for work whose final cost is not yet settled."
          },
          "available_nanodollars": {
            "type": "string",
            "maxLength": 20,
            "pattern": "^(0|-?[1-9][0-9]{0,17}|-?[1-8][0-9]{18}|-?9[01][0-9]{17}|-?92[0-1][0-9]{16}|-?922[0-2][0-9]{15}|-?9223[0-2][0-9]{14}|-?92233[0-6][0-9]{13}|-?922337[0-1][0-9]{12}|-?92233720[0-2][0-9]{10}|-?922337203[0-5][0-9]{9}|-?9223372036[0-7][0-9]{8}|-?92233720368[0-4][0-9]{7}|-?922337203685[0-3][0-9]{6}|-?9223372036854[0-6][0-9]{5}|-?92233720368547[0-6][0-9]{4}|-?922337203685477[0-4][0-9]{3}|-?9223372036854775[0-7][0-9]{2}|922337203685477580[0-7]|-922337203685477580[0-8])$",
            "description": "Canonical base-10 signed 64-bit nanodollar amount as a string, preserving exact integer precision across JSON clients; equals settled_nanodollars minus held_nanodollars."
          },
          "held_sandbox_count": {
            "type": "integer",
            "minimum": 0,
            "description": "How many sandboxes hold a reservation that makes up `held_nanodollars`; a create whose outcome is not yet known counts as one until it resolves. Absent from responses of a Cloud that does not report it yet."
          },
          "spent_today_nanodollars": {
            "type": "string",
            "maxLength": 19,
            "pattern": "^(0|[1-9][0-9]{0,17}|[1-8][0-9]{18}|9[01][0-9]{17}|92[0-1][0-9]{16}|922[0-2][0-9]{15}|9223[0-2][0-9]{14}|92233[0-6][0-9]{13}|922337[0-1][0-9]{12}|92233720[0-2][0-9]{10}|922337203[0-5][0-9]{9}|9223372036[0-7][0-9]{8}|92233720368[0-4][0-9]{7}|922337203685[0-3][0-9]{6}|9223372036854[0-6][0-9]{5}|92233720368547[0-6][0-9]{4}|922337203685477[0-4][0-9]{3}|9223372036854775[0-7][0-9]{2}|922337203685477580[0-7])$",
            "description": "Managed sandbox charges settled since 00:00 UTC today, for the whole organization. Open reservations are not included; they show in `held_nanodollars`. Absent from responses of a Cloud that does not report it yet."
          },
          "spent_this_month_nanodollars": {
            "type": "string",
            "maxLength": 19,
            "pattern": "^(0|[1-9][0-9]{0,17}|[1-8][0-9]{18}|9[01][0-9]{17}|92[0-1][0-9]{16}|922[0-2][0-9]{15}|9223[0-2][0-9]{14}|92233[0-6][0-9]{13}|922337[0-1][0-9]{12}|92233720[0-2][0-9]{10}|922337203[0-5][0-9]{9}|9223372036[0-7][0-9]{8}|92233720368[0-4][0-9]{7}|922337203685[0-3][0-9]{6}|9223372036854[0-6][0-9]{5}|92233720368547[0-6][0-9]{4}|922337203685477[0-4][0-9]{3}|9223372036854775[0-7][0-9]{2}|922337203685477580[0-7])$",
            "description": "Managed sandbox charges settled since the first of this month, 00:00 UTC, for the whole organization. Absent from responses of a Cloud that does not report it yet."
          },
          "workspace_limit": {
            "description": "Headroom under the requesting workspace's spend limit; null when the workspace has none. Absent from responses of a Cloud that does not report it yet.",
            "oneOf": [
              {
                "type": "null"
              },
              {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "limit_source",
                  "period",
                  "limit_nanodollars",
                  "spent_nanodollars",
                  "remaining_nanodollars",
                  "reset_at"
                ],
                "properties": {
                  "limit_source": {
                    "type": "string",
                    "description": "Names what the limit is; the same value a spend_limit_exceeded refusal carries in details.limit_source."
                  },
                  "period": {
                    "$ref": "#/components/schemas/SpendLimitPeriod"
                  },
                  "limit_nanodollars": {
                    "type": "string",
                    "description": "The cap, as an exact nanodollar string."
                  },
                  "spent_nanodollars": {
                    "type": "string",
                    "description": "Settled charges plus open reservations counted against the cap in its period."
                  },
                  "remaining_nanodollars": {
                    "type": "string",
                    "description": "The cap minus what is counted; never below zero."
                  },
                  "reset_at": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "date-time",
                    "description": "When the period next restarts in UTC; null for a total cap."
                  }
                }
              }
            ]
          },
          "purchase_bounds_minor": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "minimum",
              "maximum"
            ],
            "properties": {
              "minimum": {
                "type": "integer",
                "minimum": 1,
                "description": "Smallest accepted top-up in US cents."
              },
              "maximum": {
                "type": "integer",
                "minimum": 1,
                "description": "Largest accepted top-up in US cents."
              }
            }
          }
        }
      },
      "SpendLimitPeriod": {
        "type": "string",
        "enum": [
          "total",
          "daily",
          "monthly"
        ]
      },
      "SpendLimitList": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "mode",
          "workspace"
        ],
        "properties": {
          "mode": {
            "type": "string",
            "enum": [
              "test",
              "live"
            ],
            "description": "Billing book mode these limits apply to."
          },
          "workspace": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/SpendLimit"
              },
              {
                "type": "null"
              }
            ]
          },
          "workspace_spent_nanodollars": {
            "description": "Managed usage counted against the workspace cap so far in its current period, holds included, as a canonical base-10 nonnegative 64-bit nanodollar string. Null when no workspace cap is set.",
            "oneOf": [
              {
                "type": "string",
                "maxLength": 19,
                "pattern": "^(0|[1-9][0-9]{0,17}|[1-8][0-9]{18}|9[01][0-9]{17}|92[0-1][0-9]{16}|922[0-2][0-9]{15}|9223[0-2][0-9]{14}|92233[0-6][0-9]{13}|922337[0-1][0-9]{12}|92233720[0-2][0-9]{10}|922337203[0-5][0-9]{9}|9223372036[0-7][0-9]{8}|92233720368[0-4][0-9]{7}|922337203685[0-3][0-9]{6}|9223372036854[0-6][0-9]{5}|92233720368547[0-6][0-9]{4}|922337203685477[0-4][0-9]{3}|9223372036854775[0-7][0-9]{2}|922337203685477580[0-7])$"
              },
              {
                "type": "null"
              }
            ]
          }
        }
      },
      "SpendLimit": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "limit_usd",
          "limit_period"
        ],
        "properties": {
          "limit_usd": {
            "$ref": "#/components/schemas/SpendLimitUsd"
          },
          "limit_period": {
            "$ref": "#/components/schemas/SpendLimitPeriod"
          }
        },
        "description": "A cap on managed compute spend. Both fields are always set; clear a cap with the delete operation."
      },
      "SpendLimitUsd": {
        "type": "string",
        "pattern": "^(?:0\\.[0-9]*[1-9][0-9]{0,8}|[1-9][0-9]*(?:\\.[0-9]{1,9})?)$",
        "description": "Positive exact USD amount as a decimal string with at most nine fractional digits."
      },
      "SpendLimitRecord": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "mode",
          "scope",
          "spend_limit"
        ],
        "properties": {
          "mode": {
            "type": "string",
            "enum": [
              "test",
              "live"
            ]
          },
          "scope": {
            "type": "string",
            "enum": [
              "workspace"
            ]
          },
          "spend_limit": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/SpendLimit"
              },
              {
                "type": "null"
              }
            ]
          }
        }
      },
      "CreateCreditPurchase": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "amount_minor"
        ],
        "properties": {
          "amount_minor": {
            "type": "integer",
            "minimum": 1,
            "description": "Top-up in whole US cents, within purchase_bounds_minor."
          },
          "expected_total_minor": {
            "type": "integer",
            "minimum": 1,
            "description": "Required for in-page card purchases; the total from the latest quote. A changed total returns 409 quote_changed with the current quote."
          },
          "payment_method_id": {
            "type": "string",
            "pattern": "^pm_[A-Za-z0-9_]+$",
            "description": "Optional saved card to charge immediately. Omit to use hosted Checkout."
          },
          "success_url": {
            "type": "string",
            "format": "uri",
            "maxLength": 2048,
            "description": "URL on the BoxRouter website the payer returns to after paying; other origins are rejected. `{PURCHASE_ID}` is replaced. Returning here does not establish payment."
          },
          "cancel_url": {
            "type": "string",
            "format": "uri",
            "maxLength": 2048,
            "description": "URL on the BoxRouter website the payer returns to after abandoning Checkout; other origins are rejected. `{PURCHASE_ID}` is replaced."
          }
        },
        "anyOf": [
          {
            "required": [
              "payment_method_id"
            ],
            "properties": {
              "payment_method_id": {
                "type": "string",
                "pattern": "^pm_[A-Za-z0-9_]+$"
              }
            }
          },
          {
            "required": [
              "success_url",
              "cancel_url"
            ],
            "properties": {
              "success_url": {
                "$ref": "#/components/schemas/success_url"
              },
              "cancel_url": {
                "$ref": "#/components/schemas/cancel_url"
              }
            }
          }
        ]
      },
      "success_url": {
        "type": "string",
        "format": "uri",
        "maxLength": 2048,
        "description": "URL on the BoxRouter website the payer returns to after paying; other origins are rejected. `{PURCHASE_ID}` is replaced. Returning here does not establish payment."
      },
      "cancel_url": {
        "type": "string",
        "format": "uri",
        "maxLength": 2048,
        "description": "URL on the BoxRouter website the payer returns to after abandoning Checkout; other origins are rejected. `{PURCHASE_ID}` is replaced."
      },
      "CreatedCreditPurchase": {
        "oneOf": [
          {
            "$ref": "#/components/schemas/StartedCreditPurchase"
          },
          {
            "$ref": "#/components/schemas/AuthenticatedCreditPurchase"
          },
          {
            "$ref": "#/components/schemas/ConfirmedSavedCardCreditPurchase"
          }
        ]
      },
      "StartedCreditPurchase": {
        "allOf": [
          {
            "$ref": "#/components/schemas/CreditPurchase"
          },
          {
            "type": "object",
            "required": [
              "checkout_url"
            ],
            "properties": {
              "status": {
                "type": "string",
                "const": "pending"
              },
              "method": {
                "type": "string",
                "const": "checkout"
              },
              "checkout_url": {
                "type": "string",
                "format": "uri",
                "description": "Hosted payment page for this purchase. Send the payer here."
              }
            },
            "not": {
              "required": [
                "authentication_url"
              ],
              "properties": {
                "authentication_url": true
              }
            }
          }
        ]
      },
      "CreditPurchase": {
        "type": "object",
        "required": [
          "id",
          "status",
          "amount_minor",
          "currency",
          "created_at",
          "updated_at"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "description": "pending until the payment provider's verified notification arrives; confirmed\nonce the payment has been verified; canceled when an unpaid Checkout session\nexpires; failed when a saved-card attempt is definitively declined. Later\nrefunds and disputes are separate adjustments and do not change this status.\nClients must handle unknown values explicitly.\n"
          },
          "amount_minor": {
            "type": "integer",
            "minimum": 1,
            "description": "Credit added to the balance, in US cents. The purchase fee is never part of it."
          },
          "fee_minor": {
            "type": "integer",
            "minimum": 0,
            "description": "BoxRouter's fee for adding credits, in US cents, charged on top of amount_minor and never credited. Zero when the purchase carried no fee. Absent on older services."
          },
          "total_minor": {
            "type": "integer",
            "minimum": 1,
            "description": "amount_minor plus fee_minor, in US cents, before any tax. This is what the payer is asked to pay. Absent on older services."
          },
          "currency": {
            "type": "string",
            "const": "usd"
          },
          "method": {
            "type": "string",
            "enum": [
              "checkout",
              "saved_card",
              "auto_top_up"
            ],
            "description": "How this purchase was started. New services report existing purchases as checkout; absent on older services."
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          },
          "failure_reason": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100,
            "description": "Short safe description present only when a saved-card attempt failed."
          },
          "adjustments": {
            "type": "array",
            "description": "Later refunds, dispute adjustments and verified dispute outcomes, oldest first.",
            "items": {
              "$ref": "#/components/schemas/CreditAdjustment"
            }
          },
          "invoice": {
            "$ref": "#/components/schemas/CreditInvoice",
            "description": "Present only after payment is confirmed and Stripe provides invoice links. Older purchases can have no invoice."
          },
          "receipt_url": {
            "type": "string",
            "format": "uri",
            "description": "Stripe receipt for the confirmed payment; never returned for an unpaid purchase. Links can change."
          },
          "refund": {
            "$ref": "#/components/schemas/CreditPurchaseRefund",
            "description": "Self-serve refund eligibility and the newest refund. Present only when refund routes are enabled; never contains a stale quote."
          }
        },
        "allOf": [
          {
            "if": {
              "properties": {
                "status": {
                  "not": {
                    "const": "confirmed"
                  }
                }
              },
              "required": [
                "status"
              ]
            },
            "then": {
              "not": {
                "anyOf": [
                  {
                    "required": [
                      "invoice"
                    ],
                    "properties": {
                      "invoice": true
                    }
                  },
                  {
                    "required": [
                      "receipt_url"
                    ],
                    "properties": {
                      "receipt_url": true
                    }
                  }
                ]
              }
            }
          },
          {
            "if": {
              "properties": {
                "status": {
                  "const": "failed"
                }
              },
              "required": [
                "status"
              ]
            },
            "then": {
              "properties": {
                "failure_reason": {
                  "$ref": "#/components/schemas/failure_reason"
                }
              },
              "required": [
                "failure_reason"
              ]
            }
          },
          {
            "if": {
              "properties": {
                "status": {
                  "not": {
                    "const": "failed"
                  }
                }
              },
              "required": [
                "status"
              ]
            },
            "then": {
              "not": {
                "required": [
                  "failure_reason"
                ],
                "properties": {
                  "failure_reason": true
                }
              }
            }
          }
        ]
      },
      "CreditAdjustment": {
        "type": "object",
        "required": [
          "kind",
          "amount_minor",
          "created_at"
        ],
        "properties": {
          "kind": {
            "type": "string",
            "enum": [
              "refund",
              "customer_refund",
              "dispute_opened",
              "dispute_won",
              "dispute_reinstated",
              "dispute_lost"
            ],
            "x-boxrouter-open-enum": true,
            "description": "Refund or dispute history. dispute_reinstated is an exact positive restoration of\nfunds returned by Stripe. dispute_lost is a verified final outcome marker and does\nnot change the credit balance.\n"
          },
          "amount_minor": {
            "type": "integer",
            "description": "Signed amount in US cents; negative reduces the balance and positive restores it.\nA dispute_reinstated adjustment is positive; a dispute_lost outcome marker has amount zero.\n"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "allOf": [
          {
            "if": {
              "properties": {
                "kind": {
                  "const": "dispute_reinstated"
                }
              },
              "required": [
                "kind"
              ]
            },
            "then": {
              "properties": {
                "amount_minor": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            }
          },
          {
            "if": {
              "properties": {
                "kind": {
                  "const": "dispute_lost"
                }
              },
              "required": [
                "kind"
              ]
            },
            "then": {
              "properties": {
                "amount_minor": {
                  "const": 0
                }
              }
            }
          }
        ]
      },
      "CreditInvoice": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "number",
          "pdf_url",
          "hosted_url"
        ],
        "properties": {
          "number": {
            "type": "string",
            "minLength": 1
          },
          "pdf_url": {
            "type": "string",
            "format": "uri"
          },
          "hosted_url": {
            "type": "string",
            "format": "uri"
          }
        }
      },
      "CreditPurchaseRefund": {
        "type": "object",
        "required": [
          "state"
        ],
        "properties": {
          "state": {
            "type": "string",
            "enum": [
              "available",
              "unavailable",
              "pending",
              "succeeded",
              "failed",
              "failed_after_success"
            ],
            "x-boxrouter-open-enum": true,
            "description": "Current refund state; clients must tolerate future values."
          },
          "disabled_reason": {
            "type": "string",
            "enum": [
              "window_closed",
              "below_minimum",
              "nothing_to_refund",
              "not_card",
              "no_invoice",
              "dispute_open",
              "fraud_review",
              "operator_refunded",
              "purchase_in_progress",
              "fee_unavailable",
              "legacy_purchase",
              "already_refunded",
              "daily_limit",
              "retry_requires_support"
            ],
            "x-boxrouter-open-enum": true,
            "description": "Why a refund cannot currently be requested."
          },
          "refundable_until": {
            "type": "string",
            "format": "date-time",
            "description": "Exclusive 24-hour deadline from payment confirmation, in UTC."
          },
          "fee_minor": {
            "type": "integer",
            "minimum": 0,
            "description": "Stripe processing fee in US cents, which is not refunded."
          },
          "latest_refund": {
            "$ref": "#/components/schemas/CreditRefundSummary",
            "description": "Most recent refund, including pending or failed refunds."
          }
        }
      },
      "CreditRefundSummary": {
        "type": "object",
        "required": [
          "id",
          "status",
          "unused",
          "total",
          "fee",
          "card",
          "requested_at"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "succeeded",
              "failed",
              "failed_after_success"
            ],
            "x-boxrouter-open-enum": true
          },
          "unused": {
            "type": "integer",
            "minimum": 0,
            "description": "Credit debited from the balance in US cents."
          },
          "total": {
            "type": "integer",
            "minimum": 0,
            "description": "Stripe's total refund including tax, in US cents."
          },
          "fee": {
            "type": "integer",
            "minimum": 0,
            "description": "Original Stripe processing fee retained, in US cents."
          },
          "card": {
            "$ref": "#/components/schemas/RefundCard"
          },
          "requested_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "RefundCard": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "type"
        ],
        "properties": {
          "brand": {
            "type": "string"
          },
          "last4": {
            "type": "string",
            "pattern": "^[0-9]{4}$",
            "description": "Last four digits of the refunded card; absent for a Link refund, which has no card number."
          },
          "type": {
            "type": "string",
            "enum": [
              "card",
              "link"
            ],
            "x-boxrouter-open-enum": true
          }
        },
        "allOf": [
          {
            "if": {
              "properties": {
                "type": {
                  "const": "card"
                }
              },
              "required": [
                "type"
              ]
            },
            "then": {
              "required": [
                "brand",
                "last4"
              ]
            }
          },
          {
            "if": {
              "properties": {
                "type": {
                  "const": "link"
                }
              },
              "required": [
                "type"
              ]
            },
            "then": {
              "not": {
                "required": [
                  "last4"
                ],
                "properties": {
                  "last4": true
                }
              }
            }
          }
        ]
      },
      "failure_reason": {
        "type": "string",
        "minLength": 1,
        "maxLength": 100,
        "description": "Short safe description present only when a saved-card attempt failed."
      },
      "AuthenticatedCreditPurchase": {
        "allOf": [
          {
            "$ref": "#/components/schemas/CreditPurchase"
          },
          {
            "type": "object",
            "required": [
              "authentication_url"
            ],
            "properties": {
              "status": {
                "type": "string",
                "const": "pending"
              },
              "method": {
                "type": "string",
                "const": "saved_card"
              },
              "authentication_url": {
                "type": "string",
                "format": "uri",
                "description": "Stripe-hosted invoice page for required authentication; poll the purchase after returning to the dashboard."
              },
              "payment_intent_client_secret": {
                "type": "string",
                "minLength": 1,
                "description": "Stripe PaymentIntent client secret for in-page confirmation when 3DS is required."
              }
            },
            "not": {
              "required": [
                "checkout_url"
              ],
              "properties": {
                "checkout_url": true
              }
            }
          }
        ]
      },
      "ConfirmedSavedCardCreditPurchase": {
        "allOf": [
          {
            "$ref": "#/components/schemas/CreditPurchase"
          },
          {
            "type": "object",
            "properties": {
              "status": {
                "type": "string",
                "const": "confirmed"
              },
              "method": {
                "type": "string",
                "const": "saved_card"
              }
            },
            "not": {
              "anyOf": [
                {
                  "required": [
                    "checkout_url"
                  ],
                  "properties": {
                    "checkout_url": true
                  }
                },
                {
                  "required": [
                    "authentication_url"
                  ],
                  "properties": {
                    "authentication_url": true
                  }
                }
              ]
            }
          }
        ]
      },
      "CreditPurchaseDeclined": {
        "allOf": [
          {
            "$ref": "#/components/schemas/ApiErrorResponse"
          },
          {
            "type": "object",
            "properties": {
              "error": {
                "type": "object",
                "required": [
                  "details"
                ],
                "properties": {
                  "code": {
                    "type": "string",
                    "const": "payment_declined"
                  },
                  "outcome": {
                    "type": "string",
                    "const": "not_started"
                  },
                  "details": {
                    "type": "object",
                    "required": [
                      "purchase_id",
                      "failure_reason"
                    ],
                    "properties": {
                      "purchase_id": {
                        "type": "string",
                        "minLength": 1
                      },
                      "failure_reason": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 100
                      }
                    }
                  }
                }
              }
            }
          }
        ]
      },
      "CreditPurchaseList": {
        "type": "object",
        "required": [
          "data",
          "next_cursor"
        ],
        "properties": {
          "data": {
            "type": "array",
            "description": "Workspace purchases ordered by creation time and ID descending.",
            "items": {
              "$ref": "#/components/schemas/CreditPurchase"
            }
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ],
            "description": "Opaque cursor for the next page; null at the end. Scoped to this workspace."
          }
        }
      },
      "CreditPurchaseQuoteRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "amount_minor"
        ],
        "properties": {
          "amount_minor": {
            "type": "integer",
            "minimum": 1,
            "description": "Top-up principal in whole US cents."
          }
        }
      },
      "ManagedCreditUsageList": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "data",
          "next_cursor"
        ],
        "properties": {
          "data": {
            "type": "array",
            "description": "Managed-compute credit movements, newest first. Settled nonzero charges, later corrections to them, reservations still held, and reservations released with no charge. BYOK work and internal cost evidence are excluded.",
            "items": {
              "$ref": "#/components/schemas/ManagedCreditUsage"
            }
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "maxLength": 512,
            "description": "Opaque workspace-scoped continuation cursor; null when no older charges remain."
          }
        }
      },
      "ManagedCreditUsage": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "amount_nanodollars",
          "created_at"
        ],
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^[0-9a-f]{24}$",
            "description": "Stable opaque activity ID; it does not reveal the internal reservation ID."
          },
          "kind": {
            "type": "string",
            "enum": [
              "sandbox_charge",
              "sandbox_correction",
              "sandbox_hold",
              "sandbox_release"
            ],
            "x-boxrouter-open-enum": true,
            "description": "`sandbox_charge`: a sandbox's charge as first settled. `sandbox_correction`: a later\nchange to that charge. `sandbox_hold`: a reservation still held against the balance.\n`sandbox_release`: a reservation released with no charge. Absent from responses of a\nCloud that does not report it yet, where every row is a `sandbox_charge`. Clients must\nhandle unknown values explicitly.\n"
          },
          "sandbox_id": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "maxLength": 128,
            "description": "The sandbox this row belongs to. Null when the sandbox cannot be identified. Absent where `kind` is absent."
          },
          "sandbox_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "The sandbox's name label, when it has one. Null otherwise. Absent where `kind` is absent."
          },
          "key_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "The workspace API key whose request the row belongs to. Null when the work was not made through an API key, such as a dashboard action, or the key can no longer be identified. Absent where `kind` is absent and on a Cloud that does not report it yet."
          },
          "amount_nanodollars": {
            "type": "string",
            "maxLength": 20,
            "pattern": "^(-?[1-9][0-9]{0,18})$",
            "description": "The credit the row moved, in billionths of a US dollar, never including the provider's\ncost. For a `sandbox_charge` it is the positive debit. For a `sandbox_correction` it is\nthe change to the charge: positive when the charge went up and the balance was debited,\nnegative when it went down and the balance was credited. For a `sandbox_hold` it is the\ncredit currently reserved, positive. For a `sandbox_release` it is the reserved credit\nreturned, positive.\n"
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Time the debit settled, the correction was recorded, the reservation last changed, or the reservation was released."
          }
        }
      },
      "UsageReportPage": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "as_of",
          "data",
          "next_cursor"
        ],
        "properties": {
          "as_of": {
            "type": "string",
            "format": "date-time",
            "description": "UTC timestamp of the repeatable-read snapshot used to compose this page."
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/UsageReportRow"
            }
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "maxLength": 512
          }
        }
      },
      "UsageReportRow": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "period",
          "group_key",
          "sandbox_count",
          "compute_seconds",
          "compute_seconds_unknown_sandboxes",
          "charge_usd",
          "held_usd",
          "byok_provider_cost_usd",
          "byok_provider_cost_unknown_sandboxes"
        ],
        "properties": {
          "period": {
            "type": "string",
            "minLength": 1,
            "description": "Inclusive UTC date range for non-day groups, UTC day for day groups, or `current` for the current open-hold snapshot."
          },
          "group_key": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "description": "Provider, UTC day (or `current`), API-key ID, or sandbox ID; null means the source key could not be attributed."
          },
          "sandbox_count": {
            "type": "integer",
            "minimum": 1
          },
          "compute_seconds": {
            "type": [
              "object",
              "null"
            ],
            "additionalProperties": false,
            "required": [
              "low",
              "high"
            ],
            "properties": {
              "low": {
                "$ref": "#/components/schemas/Seconds"
              },
              "high": {
                "$ref": "#/components/schemas/Seconds"
              }
            },
            "description": "Exact conservative interval bounds in seconds; null when no computable interval is present or any contributing duration is unknown."
          },
          "compute_seconds_unknown_sandboxes": {
            "type": "integer",
            "minimum": 0,
            "description": "Sandboxes with missing or uncertain compute-duration evidence."
          },
          "charge_usd": {
            "$ref": "#/components/schemas/Usd",
            "description": "Exact settled managed-compute charge recognized within this row."
          },
          "held_usd": {
            "$ref": "#/components/schemas/Usd",
            "description": "Current managed reservation amount; this is a snapshot and may change on the next request."
          },
          "byok_provider_cost_usd": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/Usd"
              },
              {
                "type": "null"
              }
            ],
            "description": "Exact BYOK provider cost in USD, from each sandbox's provider-reported cost or its provider usage records priced at list rates. Null when any contributing BYOK sandbox has an unknown provider cost; partial subtotals and local-clock costs are never returned. This is separate from the BoxRouter customer charge."
          },
          "byok_provider_cost_unknown_sandboxes": {
            "type": "integer",
            "minimum": 0,
            "description": "BYOK sandboxes whose provider cost is unknown. Any positive count makes byok_provider_cost_usd null."
          },
          "pending_holds": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "count",
              "oldest_age_seconds",
              "cause"
            ],
            "properties": {
              "count": {
                "type": "integer",
                "minimum": 1,
                "description": "Managed holds in this row whose create has no known sandbox identity yet. They keep counting in `held_usd` until an operator binds or settles them."
              },
              "oldest_age_seconds": {
                "type": [
                  "integer",
                  "null"
                ],
                "minimum": 0,
                "description": "Seconds since the oldest such hold was reserved; null when unknown."
              },
              "cause": {
                "type": "string",
                "enum": [
                  "create_outcome_unknown"
                ],
                "x-boxrouter-open-enum": true,
                "description": "Why the holds are pending. Clients must tolerate causes they do not know."
              }
            },
            "description": "Present only when the row includes such holds; absent otherwise. Absence means none, not zero."
          }
        },
        "allOf": [
          {
            "if": {
              "properties": {
                "byok_provider_cost_unknown_sandboxes": {
                  "minimum": 1
                }
              },
              "required": [
                "byok_provider_cost_unknown_sandboxes"
              ]
            },
            "then": {
              "properties": {
                "byok_provider_cost_usd": {
                  "type": "null"
                }
              }
            }
          }
        ]
      },
      "Seconds": {
        "type": "string",
        "pattern": "^(0|[1-9][0-9]*)(\\.[0-9]*[1-9])?$",
        "description": "Exact decimal string; never rounded through a JSON floating-point number."
      },
      "Usd": {
        "type": "string",
        "pattern": "^(0|[1-9][0-9]*)\\.[0-9]{9}$",
        "description": "Exact USD decimal string with nanodollar precision."
      },
      "CancelCreditPurchase": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "success_url": {
            "type": "string",
            "format": "uri",
            "maxLength": 2048,
            "description": "BoxRouter website URL for a recovered Checkout session."
          },
          "cancel_url": {
            "type": "string",
            "format": "uri",
            "maxLength": 2048,
            "description": "BoxRouter website URL used if recovered Checkout is canceled."
          }
        }
      },
      "RedeemCreditPromotion": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "code"
        ],
        "properties": {
          "code": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128,
            "description": "The promotion code as the customer typed it."
          }
        }
      },
      "CreditPromotionList": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "data"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CreditPromotion"
            }
          }
        }
      },
      "BillingDetails": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "name",
          "email",
          "address",
          "tax_id"
        ],
        "properties": {
          "name": {
            "type": [
              "string",
              "null"
            ]
          },
          "email": {
            "type": [
              "string",
              "null"
            ]
          },
          "address": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/BillingAddress"
              },
              {
                "type": "null"
              }
            ]
          },
          "tax_id": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/BillingTaxId"
              },
              {
                "type": "null"
              }
            ]
          }
        }
      },
      "BillingAddress": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "line1",
          "line2",
          "city",
          "state",
          "postal_code",
          "country"
        ],
        "properties": {
          "line1": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 200
          },
          "line2": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 200
          },
          "city": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 200
          },
          "state": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 200
          },
          "postal_code": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 50
          },
          "country": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^[A-Z]{2}$",
            "description": "ISO 3166-1 alpha-2 country code, or null when unset."
          }
        }
      },
      "BillingTaxId": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "type",
          "value"
        ],
        "properties": {
          "type": {
            "type": "string",
            "description": "Stripe tax ID type; unknown future types are returned unchanged."
          },
          "value": {
            "type": "string"
          },
          "verification_status": {
            "type": "string",
            "description": "Stripe verification status when available (pending, verified, unverified or unavailable); clients must handle unknown values."
          }
        }
      },
      "UpdateBillingDetails": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "name",
          "email",
          "address"
        ],
        "properties": {
          "name": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "maxLength": 256
          },
          "email": {
            "type": [
              "string",
              "null"
            ],
            "format": "email",
            "maxLength": 512
          },
          "address": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/BillingAddress"
              },
              {
                "type": "null"
              }
            ]
          },
          "tax_id": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/BillingTaxIdInput"
              },
              {
                "type": "null"
              }
            ],
            "description": "One business tax ID. Null or omission removes existing customer tax IDs; changes apply to future invoices."
          }
        }
      },
      "BillingTaxIdInput": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "type",
          "value"
        ],
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "ad_nrt",
              "ae_trn",
              "al_tin",
              "am_tin",
              "ao_tin",
              "ar_cuit",
              "au_abn",
              "au_arn",
              "aw_tin",
              "az_tin",
              "ba_tin",
              "bb_tin",
              "bd_bin",
              "bf_ifu",
              "bg_uic",
              "bh_vat",
              "bj_ifu",
              "bo_tin",
              "br_cnpj",
              "br_cpf",
              "bs_tin",
              "by_tin",
              "ca_bn",
              "ca_gst_hst",
              "ca_pst_bc",
              "ca_pst_mb",
              "ca_pst_sk",
              "ca_qst",
              "cd_nif",
              "ch_uid",
              "ch_vat",
              "cl_tin",
              "cm_niu",
              "cn_tin",
              "co_nit",
              "cr_tin",
              "cv_nif",
              "de_stn",
              "do_rcn",
              "ec_ruc",
              "eg_tin",
              "es_cif",
              "et_tin",
              "eu_oss_vat",
              "eu_vat",
              "fo_vat",
              "gb_vat",
              "ge_vat",
              "gi_tin",
              "gn_nif",
              "hk_br",
              "hr_oib",
              "hu_tin",
              "ic_nif",
              "id_npwp",
              "il_vat",
              "in_gst",
              "is_vat",
              "it_cf",
              "jp_cn",
              "jp_rn",
              "jp_trn",
              "ke_pin",
              "kg_tin",
              "kh_tin",
              "kr_brn",
              "kz_bin",
              "la_tin",
              "li_uid",
              "li_vat",
              "lk_vat",
              "ma_vat",
              "md_vat",
              "me_pib",
              "mk_vat",
              "mr_nif",
              "mx_rfc",
              "my_frp",
              "my_itn",
              "my_sst",
              "ng_tin",
              "no_vat",
              "no_voec",
              "np_pan",
              "nz_gst",
              "om_vat",
              "pe_ruc",
              "ph_tin",
              "pl_nip",
              "py_ruc",
              "ro_tin",
              "rs_pib",
              "ru_inn",
              "ru_kpp",
              "sa_vat",
              "sg_gst",
              "sg_uen",
              "si_tin",
              "sn_ninea",
              "sr_fin",
              "sv_nit",
              "th_vat",
              "tj_tin",
              "tr_tin",
              "tw_vat",
              "tz_vat",
              "ua_vat",
              "ug_tin",
              "us_ein",
              "uy_ruc",
              "uz_tin",
              "uz_vat",
              "ve_rif",
              "vn_tin",
              "za_vat",
              "zm_tin",
              "zw_tin"
            ],
            "description": "Customer tax ID type accepted by Stripe. See https://docs.stripe.com/api/tax_ids/customer_create."
          },
          "value": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          },
          "verification_status": {
            "type": "string",
            "readOnly": true,
            "description": "Ignored on update; supplied by Stripe on reads."
          }
        }
      },
      "CreditAlerts": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "low_balance_threshold_minor",
          "email_delivery"
        ],
        "properties": {
          "low_balance_threshold_minor": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1,
            "maximum": 9007199254740991,
            "description": "Optional low-balance alert level in US cents; null disables it. Evaluating a balance below a newly enabled level alerts immediately. Zero-balance alerts are automatic. Alerts re-arm when balance recovers to the level (or above zero)."
          },
          "email_delivery": {
            "type": "string",
            "enum": [
              "configured",
              "log_only"
            ],
            "description": "Whether SMTP and a verified workspace-owner address are configured for low- and zero-balance notices; configured does not guarantee successful delivery."
          }
        }
      },
      "CreditAlertsUpdate": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "low_balance_threshold_minor"
        ],
        "properties": {
          "low_balance_threshold_minor": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1,
            "maximum": 9007199254740991,
            "description": "Optional low-balance alert level in US cents; null disables it. Evaluating a balance below a newly enabled level alerts immediately. Zero-balance alerts are automatic. Alerts re-arm when balance recovers to the level (or above zero)."
          }
        }
      },
      "CreditPaymentMethodList": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "data"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CreditPaymentMethod"
            }
          }
        }
      },
      "CreditPaymentMethod": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id"
        ],
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^pm_[A-Za-z0-9_]+$"
          },
          "brand": {
            "type": [
              "string",
              "null"
            ],
            "description": "Card brand; absent for Link methods."
          },
          "last4": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^[0-9]{4}$",
            "description": "Last four card digits; absent for Link methods."
          },
          "exp_month": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1,
            "maximum": 12,
            "description": "Card expiry month; absent for Link methods."
          },
          "exp_year": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 2000,
            "maximum": 9999,
            "description": "Card expiry year; absent for Link methods."
          },
          "default": {
            "type": "boolean",
            "description": "True for the workspace's one default saved card; absent on older services."
          },
          "priority": {
            "type": "integer",
            "minimum": 1,
            "description": "One-based charge order for automatic top-up; lower priorities are tried first."
          },
          "type": {
            "type": "string",
            "enum": [
              "card",
              "link"
            ],
            "x-boxrouter-open-enum": true,
            "description": "Payment method type. Link is a card-backed method saved through Stripe Link."
          },
          "email": {
            "type": "string",
            "format": "email",
            "description": "Link account email; present only when type is link."
          }
        },
        "allOf": [
          {
            "if": {
              "properties": {
                "type": {
                  "const": "link"
                }
              },
              "required": [
                "type"
              ]
            },
            "then": {
              "required": [
                "email"
              ],
              "properties": {
                "brand": {
                  "type": "null"
                },
                "last4": {
                  "type": "null"
                },
                "exp_month": {
                  "type": "null"
                },
                "exp_year": {
                  "type": "null"
                }
              }
            }
          },
          {
            "if": {
              "properties": {
                "type": {
                  "const": "card"
                }
              },
              "required": [
                "type"
              ]
            },
            "then": {
              "required": [
                "brand",
                "last4",
                "exp_month",
                "exp_year"
              ],
              "properties": {
                "brand": {
                  "type": "string"
                },
                "last4": {
                  "type": "string",
                  "pattern": "^[0-9]{4}$"
                },
                "exp_month": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 12
                },
                "exp_year": {
                  "type": "integer",
                  "minimum": 2000,
                  "maximum": 9999
                }
              }
            }
          }
        ]
      },
      "CreatePaymentMethodSetup": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "success_url",
          "cancel_url"
        ],
        "properties": {
          "success_url": {
            "type": "string",
            "format": "uri",
            "maxLength": 2048,
            "description": "BoxRouter website URL after setup; `{SETUP_ID}` is replaced. Returning here does not prove setup completed."
          },
          "cancel_url": {
            "type": "string",
            "format": "uri",
            "maxLength": 2048,
            "description": "BoxRouter website URL if the payer abandons setup."
          }
        }
      },
      "StartedPaymentMethodSetup": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "status",
          "checkout_url"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "confirmed",
              "canceled"
            ],
            "description": "Confirmed only after Stripe reports the setup succeeded."
          },
          "checkout_url": {
            "type": "string",
            "format": "uri",
            "description": "Stripe-hosted setup page; no payment is collected."
          }
        }
      },
      "CreditSetupIntent": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "client_secret",
          "publishable_key"
        ],
        "properties": {
          "client_secret": {
            "type": "string",
            "minLength": 1
          },
          "publishable_key": {
            "type": "string",
            "minLength": 1
          }
        }
      },
      "ReorderCreditPaymentMethods": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "payment_method_ids"
        ],
        "properties": {
          "payment_method_ids": {
            "type": "array",
            "minItems": 1,
            "uniqueItems": true,
            "items": {
              "type": "string",
              "pattern": "^pm_[A-Za-z0-9_]+$"
            },
            "description": "Complete order of the workspace's saved card and Link payment methods."
          }
        }
      },
      "PaymentMethodSetup": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "status"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "confirmed",
              "canceled"
            ],
            "description": "Confirmed only after Stripe reports the setup succeeded."
          }
        }
      },
      "CreditAutoTopUp": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "enabled",
          "threshold_minor",
          "amount_minor",
          "email_delivery"
        ],
        "properties": {
          "enabled": {
            "type": "boolean"
          },
          "threshold_minor": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0,
            "description": "Start one top-up when available credit falls below this US-cent trigger level; null until configured."
          },
          "amount_minor": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1,
            "description": "Top-up in whole US cents, within current purchase_bounds_minor; null until configured."
          },
          "last_attempt": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "purchase_id",
              "status",
              "at"
            ],
            "properties": {
              "purchase_id": {
                "type": "string"
              },
              "status": {
                "type": "string",
                "enum": [
                  "pending",
                  "confirmed",
                  "failed"
                ]
              },
              "at": {
                "type": "string",
                "format": "date-time"
              },
              "fallback_card": {
                "$ref": "#/components/schemas/MaskedCreditCard",
                "description": "Set when a payment method after the first in priority order was charged; Link methods include their account email."
              }
            },
            "description": "Most recent top-up attempt, if one has been made."
          },
          "disabled_reason": {
            "type": "string",
            "enum": [
              "payment_declined",
              "authentication_required",
              "payment_method_required",
              "refund_accepted",
              "all_cards_failed"
            ],
            "x-boxrouter-open-enum": true,
            "description": "Why auto top-up was disabled after a decline, required authentication, or removal of the last saved card."
          },
          "email_delivery": {
            "type": "string",
            "enum": [
              "configured",
              "log_only"
            ],
            "description": "Whether SMTP and a verified workspace-owner address are configured for auto-top-up failure notices; configured does not guarantee successful delivery."
          }
        },
        "allOf": [
          {
            "if": {
              "properties": {
                "enabled": {
                  "const": true
                }
              },
              "required": [
                "enabled"
              ]
            },
            "then": {
              "properties": {
                "threshold_minor": {
                  "type": "integer",
                  "minimum": 0
                },
                "amount_minor": {
                  "type": "integer",
                  "minimum": 1
                }
              },
              "not": {
                "required": [
                  "disabled_reason"
                ],
                "properties": {
                  "disabled_reason": true
                }
              }
            }
          }
        ]
      },
      "UpdateCreditAutoTopUp": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "enabled",
          "threshold_minor",
          "amount_minor"
        ],
        "properties": {
          "enabled": {
            "type": "boolean"
          },
          "threshold_minor": {
            "type": "integer",
            "minimum": 0,
            "description": "Start one top-up when available credit falls below this US-cent trigger level."
          },
          "amount_minor": {
            "type": "integer",
            "minimum": 1,
            "description": "Top-up in whole US cents, within the current purchase_bounds_minor."
          }
        }
      },
      "OpenSandboxTerminal": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "columns": {
            "$ref": "#/components/schemas/columns"
          },
          "rows": {
            "$ref": "#/components/schemas/rows"
          },
          "timeout_seconds": {
            "x-boxrouter-input-error": "Terminal timeout_seconds must be an integer from 1 to 3600",
            "type": "integer",
            "minimum": 1,
            "maximum": 3600,
            "default": 600,
            "description": "Latest end of the shell. The API worker stays with the terminal for this long."
          }
        }
      },
      "columns": {
        "x-boxrouter-input-error": "Terminal columns must be an integer from 1 to 1000",
        "type": "integer",
        "minimum": 1,
        "maximum": 1000,
        "default": 80
      },
      "rows": {
        "x-boxrouter-input-error": "Terminal rows must be an integer from 1 to 1000",
        "type": "integer",
        "minimum": 1,
        "maximum": 1000,
        "default": 24
      },
      "SandboxTerminal": {
        "type": "object",
        "required": [
          "id",
          "sandbox_id",
          "state",
          "exit_code"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "sandbox_id": {
            "type": "string"
          },
          "state": {
            "type": "string",
            "description": "Known states are running, exited and unknown."
          },
          "exit_code": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Present only after a confirmed shell exit; 129 follows a hang-up. Null is not success."
          }
        }
      },
      "SandboxTerminalEventSSE": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "data"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Hosted replay cursor when supplied; availability and retention follow the operation."
          },
          "event": {
            "type": "string"
          },
          "data": {
            "$ref": "#/components/schemas/SandboxTerminalEvent"
          }
        },
        "description": "SSE transport envelope. The JSON payload retains its own type and native fields; EOF is not workload completion."
      },
      "SandboxTerminalEvent": {
        "oneOf": [
          {
            "$ref": "#/components/schemas/SandboxTerminalOutputEvent"
          },
          {
            "$ref": "#/components/schemas/SandboxTerminalExitEvent"
          },
          {
            "$ref": "#/components/schemas/SandboxTerminalErrorEvent"
          }
        ],
        "discriminator": {
          "propertyName": "type",
          "mapping": {
            "output": "#/components/schemas/SandboxTerminalOutputEvent",
            "exit": "#/components/schemas/SandboxTerminalExitEvent",
            "error": "#/components/schemas/SandboxTerminalErrorEvent"
          }
        }
      },
      "SandboxTerminalOutputEvent": {
        "type": "object",
        "required": [
          "type",
          "sequence",
          "data_base64"
        ],
        "properties": {
          "type": {
            "type": "string",
            "const": "output"
          },
          "sequence": {
            "type": "integer",
            "minimum": 0
          },
          "data_base64": {
            "type": "string",
            "contentEncoding": "base64",
            "description": "Exact PTY output bytes. Chunk boundaries may change."
          }
        }
      },
      "SandboxTerminalExitEvent": {
        "type": "object",
        "required": [
          "type",
          "sequence",
          "exit_code"
        ],
        "properties": {
          "type": {
            "type": "string",
            "const": "exit"
          },
          "sequence": {
            "type": "integer",
            "minimum": 0
          },
          "exit_code": {
            "type": "integer"
          }
        }
      },
      "SandboxTerminalErrorEvent": {
        "type": "object",
        "required": [
          "type",
          "error"
        ],
        "properties": {
          "type": {
            "type": "string",
            "const": "error"
          },
          "sequence": {
            "type": "integer",
            "minimum": 0
          },
          "error": {
            "$ref": "#/components/schemas/error"
          }
        }
      },
      "error": {
        "type": "object",
        "required": [
          "code",
          "message",
          "request_id",
          "outcome",
          "retry",
          "retry_after_seconds"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable machine category. Operation failures use SandboxProviderSpec error codes,\nincluding invalid_request, invalid_state, not_found, unauthorized,\nincompatible_requirements, no_eligible_route, capacity_unavailable,\ncapability_unavailable, contract_violation, resource_limit, timeout and\nprovider_error. Hosted service failures add method_not_allowed,\nunauthenticated, forbidden, actions_sandbox_protected,\ninsufficient_credit, spend_limit_exceeded,\nprovider_not_enabled, credentials_rejected, conflict, rate_limited, provider_quota, request_timeout, overloaded,\ndatabase_unavailable, payment_method_required, payment_declined, promotion_already_redeemed, account_exists, and internal_error. unsupported_feature and\noutput_limit are earlier names still returned by some routes.\nOrganization and membership operations also use organization_changed, last_admin,\nstale_membership, directory_managed and change_in_progress. Key ownership and\ninvitation operations use idempotency_key_reused and conflict.\nCredit refunds and purchase quotes also use refund_window_closed,\nnothing_to_refund, refund_below_minimum, refund_in_progress,\npurchase_in_progress, dispute_open, already_refunded,\nrefund_amount_changed, refund_fee_unavailable, quote_changed,\nsession_required, refund_daily_limit, refund_rate_limit,\nrefund_retry_requires_support, idempotency_key_reused and fraud_review.\nCard setup adds card_setup_rate_limit (429, with Retry-After): a workspace may start five\ncard setups an hour.\nA provider that refuses the request for its own plan or quota limit answers\n429 provider_quota with the provider's words in native_message; rate_limited is\nBoxRouter's own limit.\nRouting Prevent Overrides refuses a request containing preferences.order,\npreferences.sort or preferences.allow_fallbacks with routing_overrides_forbidden,\noutcome not_started and details.fields naming the prohibited inputs. No provider\neffect occurs.\nLaunch operations also use invalid_request, secret_missing, agent_not_found,\nno_eligible_route and launch_failed.\nA process or terminal is observed by one API task. When that task stops, process\noutput, result and stdin answer 410 process_observer_lost (reading or cancelling the\nprocess still works), and a terminal on a provider that cannot reattach it answers\n410 terminal_observer_lost. invalid_observer_hop (403) refuses an internal hop\nbetween API tasks that is not signed; clients never send one.\nOpening a preview that the provider answered with other access than the request\nasked for returns 502 preview_access_refused: that preview is never returned, and\ndetails say whether it was ended.\nStarting a process with wait_for_port answers 409 port_not_listening, outcome partial,\nwhen the process exits before the port accepts connections or the port stays closed for\n30 seconds; the process is ended and details carry the output so far.\nA request that must store content (a volume, a saved artifact) under transient content\nretention answers 409 privacy_persistence_conflict with outcome not_started.\nA sandbox request that stops before anything is created also answers\nlifetime_cap_exceeded, knob_not_named and unrecognised_word (400), and price_unknown and\npolicy_denied (409), each with outcome not_started; the Actions codes job_claim_lost,\nactions_authority_changed, actions_candidate_ceiling_withdrawn and\nactions_candidate_outside_ceiling (409) say the job's claim, settings or admitted routes\nchanged; provider_budget_exhausted (409) says a run's provider budget allows no\nfurther create. A create that names an image Cloud cannot use answers 400\nimage_architecture_unsupported, image_digest_resolution_failed,\nimage_preparation_unsupported or private_image_managed_route_unavailable, and\nprivacy_admission_unavailable when privacy cannot be enforced; each says what to change.\nLaunch and source-repository refusals name the repository or manifest fault (code_ref_not_found,\ncode_repository_*, source_*, invalid_source_manifest, invalid_manifest_encoding,\ninvalid_run_spec, repository_*, reserved_env_refused, launch_run_position_conflict,\ncode_reference_moved, dockerfile_context_unsupported, image_tag_unresolved,\nrecovery_sandbox_mismatch); the GitHub-side ones (source_rate_limited,\nsource_resolution_failed, source_resolution_timeout, code_repository_resolution_failed)\nare safe to resend. image_setup_timeout, managed_funding_unavailable,\nlifetime_funding_conflict, candidate_admission_unavailable, secrets_unavailable and the\nActions candidate codes (actions_candidate_record_invalid, actions_create_budget_exhausted,\nactions_create_format_mismatch) complete the creation and extension refusals.\ndispatch_limit_reached, inline_secret_values_refused and launch_incomplete come from\nlaunch runs, provider_policy_unknown from an operation whose privacy evidence cannot be\nverified, and quota_exceeded from a full managed provider account.\nVolume operations also use volume_busy, volume_lease_lost, volume_not_attached,\nvolume_incompatible, volume_save_failed and volume_restore_failed. Creating a\nsandbox on a volume whose writer is ending waits for the release (at most 120\nseconds) before it can answer volume_busy.\nA team member's new personal API key is paused until WorkOS membership sync catches\nup: it answers 403 forbidden whose message and fix say the key becomes active once\nthe team membership syncs, usually within a minute, and the call can be retried.\nClients must preserve and handle unknown categories explicitly.\n",
            "x-boxrouter-error-codes": {
              "account_exists": [
                409
              ],
              "account_unhealthy": [
                402
              ],
              "actions_authority_changed": [
                409
              ],
              "actions_candidate_ceiling_withdrawn": [
                409
              ],
              "actions_candidate_outside_ceiling": [
                409
              ],
              "actions_candidate_record_invalid": [
                409
              ],
              "actions_create_budget_exhausted": [
                409
              ],
              "actions_create_format_mismatch": [
                409
              ],
              "actions_sandbox_protected": [
                403
              ],
              "agent_not_found": [
                404
              ],
              "already_refunded": [
                409
              ],
              "authorization_error": [
                403
              ],
              "candidate_admission_unavailable": [
                503
              ],
              "capability_unavailable": [
                409,
                503
              ],
              "capability_unverified": [
                409
              ],
              "card_setup_rate_limit": [
                429
              ],
              "change_in_progress": [
                409
              ],
              "code_ref_not_found": [
                404
              ],
              "code_reference_moved": [
                409
              ],
              "code_repository_not_authorized": [
                403
              ],
              "code_repository_not_found": [
                404
              ],
              "code_repository_not_private": [
                400
              ],
              "code_repository_not_public": [
                404
              ],
              "code_repository_resolution_failed": [
                502
              ],
              "command_failed": [
                409
              ],
              "command_observation_busy": [
                409
              ],
              "conflict": [
                409
              ],
              "contract_violation": [
                409
              ],
              "credentials_rejected": [
                409,
                422
              ],
              "database_unavailable": [
                503
              ],
              "directory_managed": [
                409
              ],
              "dispatch_limit_reached": [
                409
              ],
              "dispute_open": [
                409
              ],
              "dockerfile_context_unsupported": [
                400
              ],
              "expired": [
                410
              ],
              "forbidden": [
                403
              ],
              "fraud_review": [
                409
              ],
              "gate_unavailable": [
                409
              ],
              "idempotency_key_reused": [
                409,
                422
              ],
              "identity_unavailable": [
                503
              ],
              "image_architecture_unsupported": [
                400
              ],
              "image_digest_resolution_failed": [
                400
              ],
              "image_preparation_unsupported": [
                400
              ],
              "image_setup_timeout": [
                504
              ],
              "image_tag_unresolved": [
                400
              ],
              "inline_secret_values_refused": [
                422
              ],
              "insufficient_credit": [
                402
              ],
              "internal_error": [
                500
              ],
              "invalid_manifest_encoding": [
                400
              ],
              "invalid_observer_hop": [
                403
              ],
              "invalid_request": [
                400,
                413,
                422,
                428
              ],
              "invalid_run_spec": [
                400
              ],
              "invalid_source_manifest": [
                400
              ],
              "invalid_state": [
                409
              ],
              "job_claim_lost": [
                409
              ],
              "knob_not_named": [
                400
              ],
              "last_admin": [
                409
              ],
              "launch_failed": [
                409
              ],
              "launch_incomplete": [
                409
              ],
              "launch_run_position_conflict": [
                409
              ],
              "lifetime_cap_exceeded": [
                400
              ],
              "lifetime_funding_conflict": [
                409
              ],
              "lifetime_limit": [
                409
              ],
              "lifetime_used_up": [
                409
              ],
              "managed_funding_unavailable": [
                503
              ],
              "method_not_allowed": [
                405
              ],
              "no_eligible_route": [
                409
              ],
              "not_found": [
                404
              ],
              "not_named": [
                409
              ],
              "not_running": [
                409
              ],
              "nothing_to_refund": [
                409
              ],
              "organization_changed": [
                409
              ],
              "output_limit": [
                413
              ],
              "overloaded": [
                503
              ],
              "payment_declined": [
                402
              ],
              "payment_method_required": [
                409
              ],
              "payment_provider_rejected": [
                502
              ],
              "payment_provider_unavailable": [
                503
              ],
              "payments_unavailable": [
                503
              ],
              "policy_denied": [
                409
              ],
              "port_not_listening": [
                409
              ],
              "preview_access_refused": [
                502
              ],
              "price_unknown": [
                409
              ],
              "privacy_admission_unavailable": [
                400
              ],
              "privacy_persistence_conflict": [
                409
              ],
              "private_image_managed_route_unavailable": [
                400
              ],
              "process_observer_lost": [
                410
              ],
              "promotion_already_redeemed": [
                409
              ],
              "promotion_code_invalid": [
                404
              ],
              "provider_budget_exhausted": [
                409
              ],
              "provider_error": [
                502
              ],
              "provider_not_enabled": [
                409
              ],
              "provider_policy_unknown": [
                409
              ],
              "provider_quota": [
                429
              ],
              "purchase_in_progress": [
                409
              ],
              "quota_exceeded": [
                429
              ],
              "quote_changed": [
                409
              ],
              "rate_limited": [
                429
              ],
              "recovery_sandbox_mismatch": [
                409
              ],
              "refund_amount_changed": [
                409
              ],
              "refund_below_minimum": [
                409
              ],
              "refund_daily_limit": [
                429
              ],
              "refund_fee_unavailable": [
                409
              ],
              "refund_in_progress": [
                409
              ],
              "refund_rate_limit": [
                429
              ],
              "refund_retry_requires_support": [
                409
              ],
              "refund_window_closed": [
                409
              ],
              "repository_file_unsupported": [
                400
              ],
              "repository_too_large": [
                400
              ],
              "request_timeout": [
                408
              ],
              "reserved_env_refused": [
                400,
                422
              ],
              "resource_limit": [
                413,
                507
              ],
              "routing_overrides_forbidden": [
                400
              ],
              "run_limit_exceeded": [
                429
              ],
              "sandbox_ended": [
                410
              ],
              "secret_missing": [
                400
              ],
              "secrets_unavailable": [
                503
              ],
              "session_required": [
                403
              ],
              "source_file_not_found": [
                400
              ],
              "source_file_too_large": [
                413
              ],
              "source_rate_limited": [
                503
              ],
              "source_ref_not_found": [
                400
              ],
              "source_repository_not_accessible": [
                404
              ],
              "source_repository_not_found": [
                400
              ],
              "source_repository_not_private": [
                400
              ],
              "source_repository_not_public": [
                400
              ],
              "source_resolution_failed": [
                502
              ],
              "source_resolution_timeout": [
                504
              ],
              "spend_limit_exceeded": [
                402
              ],
              "stale_membership": [
                409
              ],
              "terminal_closed": [
                410
              ],
              "terminal_observer_lost": [
                410
              ],
              "timeout": [
                504
              ],
              "unauthenticated": [
                401
              ],
              "unavailable": [
                503
              ],
              "unrecognised_word": [
                400
              ],
              "unsupported_feature": [
                422
              ],
              "volume_busy": [
                409
              ],
              "volume_incompatible": [
                409
              ],
              "volume_lease_lost": [
                409
              ],
              "volume_not_attached": [
                409
              ],
              "volume_restore_failed": [
                502
              ],
              "volume_save_failed": [
                409,
                502
              ],
              "volume_unavailable": [
                409
              ],
              "wrong_region": [
                421
              ]
            },
            "x-boxrouter-error-retry": {
              "account_exists": "after_fix",
              "account_unhealthy": "after_fix",
              "actions_authority_changed": "after_fix",
              "actions_candidate_ceiling_withdrawn": "after_fix",
              "actions_candidate_outside_ceiling": "after_fix",
              "actions_candidate_record_invalid": "after_fix",
              "actions_create_budget_exhausted": "after_fix",
              "actions_create_format_mismatch": "after_fix",
              "actions_sandbox_protected": "never",
              "agent_not_found": "after_fix",
              "already_refunded": "never",
              "authorization_error": "check_outcome",
              "candidate_admission_unavailable": "never",
              "capability_unavailable": "check_outcome",
              "capability_unverified": "after_fix",
              "card_setup_rate_limit": "safe",
              "change_in_progress": "safe",
              "code_ref_not_found": "after_fix",
              "code_reference_moved": "after_fix",
              "code_repository_not_authorized": "after_fix",
              "code_repository_not_found": "after_fix",
              "code_repository_not_private": "after_fix",
              "code_repository_not_public": "after_fix",
              "code_repository_resolution_failed": "safe",
              "command_failed": "after_fix",
              "command_observation_busy": "safe",
              "conflict": "check_outcome",
              "contract_violation": "check_outcome",
              "credentials_rejected": "after_fix",
              "database_unavailable": "check_outcome",
              "directory_managed": "never",
              "dispatch_limit_reached": "after_fix",
              "dispute_open": "after_fix",
              "dockerfile_context_unsupported": "after_fix",
              "expired": "check_outcome",
              "forbidden": "after_fix",
              "fraud_review": "safe",
              "gate_unavailable": "after_fix",
              "idempotency_key_reused": "after_fix",
              "identity_unavailable": "safe",
              "image_architecture_unsupported": "after_fix",
              "image_digest_resolution_failed": "after_fix",
              "image_preparation_unsupported": "after_fix",
              "image_setup_timeout": "after_fix",
              "image_tag_unresolved": "after_fix",
              "inline_secret_values_refused": "after_fix",
              "insufficient_credit": "after_fix",
              "internal_error": "never",
              "invalid_manifest_encoding": "after_fix",
              "invalid_observer_hop": "after_fix",
              "invalid_request": "after_fix",
              "invalid_run_spec": "after_fix",
              "invalid_source_manifest": "after_fix",
              "invalid_state": "check_outcome",
              "job_claim_lost": "after_fix",
              "knob_not_named": "after_fix",
              "last_admin": "after_fix",
              "launch_failed": "check_outcome",
              "launch_incomplete": "check_outcome",
              "launch_run_position_conflict": "after_fix",
              "lifetime_cap_exceeded": "after_fix",
              "lifetime_funding_conflict": "after_fix",
              "lifetime_limit": "check_outcome",
              "lifetime_used_up": "after_fix",
              "managed_funding_unavailable": "safe",
              "method_not_allowed": "after_fix",
              "no_eligible_route": "after_fix",
              "not_found": "check_outcome",
              "not_named": "after_fix",
              "not_running": "after_fix",
              "nothing_to_refund": "never",
              "organization_changed": "safe",
              "output_limit": "check_outcome",
              "overloaded": "safe",
              "payment_declined": "after_fix",
              "payment_method_required": "after_fix",
              "payment_provider_rejected": "check_outcome",
              "payment_provider_unavailable": "check_outcome",
              "payments_unavailable": "safe",
              "policy_denied": "after_fix",
              "port_not_listening": "after_fix",
              "preview_access_refused": "never",
              "price_unknown": "after_fix",
              "privacy_admission_unavailable": "after_fix",
              "privacy_persistence_conflict": "after_fix",
              "private_image_managed_route_unavailable": "after_fix",
              "process_observer_lost": "check_outcome",
              "promotion_already_redeemed": "never",
              "promotion_code_invalid": "after_fix",
              "provider_budget_exhausted": "never",
              "provider_error": "check_outcome",
              "provider_not_enabled": "after_fix",
              "provider_policy_unknown": "after_fix",
              "provider_quota": "after_fix",
              "purchase_in_progress": "safe",
              "quota_exceeded": "safe",
              "quote_changed": "after_fix",
              "rate_limited": "safe",
              "recovery_sandbox_mismatch": "check_outcome",
              "refund_amount_changed": "after_fix",
              "refund_below_minimum": "never",
              "refund_daily_limit": "safe",
              "refund_fee_unavailable": "safe",
              "refund_in_progress": "safe",
              "refund_rate_limit": "safe",
              "refund_retry_requires_support": "never",
              "refund_window_closed": "never",
              "repository_file_unsupported": "after_fix",
              "repository_too_large": "after_fix",
              "request_timeout": "safe",
              "reserved_env_refused": "after_fix",
              "resource_limit": "check_outcome",
              "routing_overrides_forbidden": "after_fix",
              "run_limit_exceeded": "after_fix",
              "sandbox_ended": "check_outcome",
              "secret_missing": "after_fix",
              "secrets_unavailable": "never",
              "session_required": "never",
              "source_file_not_found": "after_fix",
              "source_file_too_large": "after_fix",
              "source_rate_limited": "safe",
              "source_ref_not_found": "after_fix",
              "source_repository_not_accessible": "after_fix",
              "source_repository_not_found": "after_fix",
              "source_repository_not_private": "after_fix",
              "source_repository_not_public": "after_fix",
              "source_resolution_failed": "safe",
              "source_resolution_timeout": "safe",
              "spend_limit_exceeded": "after_fix",
              "stale_membership": "after_fix",
              "terminal_closed": "after_fix",
              "terminal_observer_lost": "after_fix",
              "timeout": "check_outcome",
              "unauthenticated": "after_fix",
              "unavailable": "safe",
              "unrecognised_word": "after_fix",
              "unsupported_feature": "after_fix",
              "volume_busy": "after_fix",
              "volume_incompatible": "after_fix",
              "volume_lease_lost": "after_fix",
              "volume_not_attached": "after_fix",
              "volume_restore_failed": "check_outcome",
              "volume_save_failed": "check_outcome",
              "volume_unavailable": "after_fix",
              "wrong_region": "after_fix"
            }
          },
          "message": {
            "type": "string"
          },
          "details": {
            "type": "object",
            "description": "Code-specific context, spelled for programs. no_eligible_route carries considered,\nexcluded, closest and nearest; knob_not_named the knob and its values;\nunrecognised_word the path, the word and the known ones; not_named the gate, what\nthe call needed beyond the grant and the corrected requirements line; gate_unavailable\nthe gate and account; lifetime_limit the ceiling and this run. A creation that\nstopped before a sandbox existed may also carry `fallbacks_allowed`, `stopped_reason`\nand `attempts`, spelled and bounded as in the sandbox route selection.\ncapability_unavailable may identify the needed capability. A launch preparation failure can follow sandbox creation;\ninspect outcome and cleanup details before creating another. Clients must\npreserve fields they do not know.\n",
            "properties": {
              "selection_version": {
                "type": "integer",
                "minimum": 0,
                "description": "Current selected organization version for organization_changed."
              },
              "considered": {
                "type": "integer",
                "minimum": 0,
                "description": "no_eligible_route only; how many routes were considered."
              },
              "excluded": {
                "type": "array",
                "description": "no_eligible_route only; every considered route that cannot serve the request. Each entry names its `provider` and the checks it failed (`failed` for a sandbox request, `reasons` and `exclusions` for a launch); clients must preserve fields they do not know.",
                "items": {
                  "type": "object",
                  "required": [
                    "provider"
                  ],
                  "properties": {
                    "provider": {
                      "type": "string"
                    }
                  }
                }
              },
              "closest": {
                "type": [
                  "object",
                  "null"
                ],
                "description": "no_eligible_route only; the excluded route that fails fewest checks, or null."
              },
              "nearest": {
                "type": "array",
                "description": "no_eligible_route only; the smallest changes that would make a route eligible, nearest first. An entry names the change (`change` and `then_eligible` for a sandbox request, `provider`, `distance` and `failing` for a launch); clients must preserve fields they do not know.",
                "items": {
                  "type": "object"
                }
              },
              "requirement": {
                "type": "string",
                "description": "The SandboxProviderSpec family whose requirement would make this operation available."
              },
              "purchase_id": {
                "type": "string",
                "description": "Retained failed credit purchase ID, when a saved-card charge was declined."
              },
              "preview": {
                "$ref": "#/components/schemas/CreditRefundPreview",
                "description": "Current refund preview returned with 409 refund_amount_changed."
              },
              "quote": {
                "$ref": "#/components/schemas/CreditPurchaseQuote",
                "description": "Current purchase quote returned with 409 quote_changed."
              },
              "redemption": {
                "$ref": "#/components/schemas/CreditPromotion",
                "description": "Original promotion redemption returned with 409 promotion_already_redeemed."
              },
              "scope": {
                "type": "string",
                "enum": [
                  "workspace"
                ],
                "description": "spend_limit_exceeded only; which configured cap refused admission."
              },
              "period": {
                "type": "string",
                "enum": [
                  "total",
                  "daily",
                  "monthly"
                ],
                "description": "spend_limit_exceeded only; the cap period that applies."
              },
              "limit_nanodollars": {
                "type": "integer",
                "minimum": 1,
                "description": "spend_limit_exceeded only; exact configured USD nanodollars."
              },
              "requested_nanodollars": {
                "type": "integer",
                "minimum": 1,
                "description": "spend_limit_exceeded only; exact proposed managed hold."
              },
              "sign_in_method": {
                "type": "string",
                "description": "account_exists only: how the existing account with this verified address signs in (google, github, email or other)."
              },
              "masked_email": {
                "type": "string",
                "description": "account_exists only: that account's address, masked as `t…@gmail.com`."
              },
              "failure_reason": {
                "type": "string",
                "maxLength": 100,
                "description": "Short safe card-decline reason; raw Stripe messages are not returned."
              },
              "names": {
                "type": "array",
                "uniqueItems": true,
                "items": {
                  "$ref": "#/components/schemas/SecretName"
                },
                "description": "All manifest secret names that could not be resolved."
              },
              "fields": {
                "type": "array",
                "uniqueItems": true,
                "items": {
                  "type": "string",
                  "enum": [
                    "preferences.order",
                    "preferences.sort",
                    "preferences.allow_fallbacks"
                  ]
                },
                "description": "routing_overrides_forbidden only; the prohibited request inputs."
              },
              "volume_id": {
                "type": "string",
                "description": "BoxRouter Volume ID involved in the error."
              },
              "writer_sandbox_id": {
                "type": "string",
                "description": "volume_busy only; the sandbox that holds the volume's writer lease, when it is a recorded sandbox."
              },
              "checkpoint": {
                "type": "integer",
                "minimum": 1,
                "description": "Volume checkpoint involved in the error."
              },
              "limit_bytes": {
                "type": "integer",
                "minimum": 0
              },
              "observed_bytes": {
                "type": "integer",
                "minimum": 0
              },
              "mismatch": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "field",
                  "recorded",
                  "requested"
                ],
                "properties": {
                  "field": {
                    "type": "string",
                    "enum": [
                      "image",
                      "arch"
                    ]
                  },
                  "recorded": {
                    "type": "string"
                  },
                  "requested": {
                    "type": "string"
                  }
                }
              },
              "volume_phase": {
                "type": "string",
                "enum": [
                  "check",
                  "branch",
                  "lease",
                  "identity",
                  "install",
                  "credential",
                  "mount",
                  "metadata",
                  "checkpoint",
                  "commit",
                  "write"
                ]
              },
              "phase": {
                "type": "string",
                "enum": [
                  "code",
                  "setup",
                  "files",
                  "background",
                  "previews"
                ],
                "description": "Preparation phase that failed."
              },
              "command": {
                "type": "string",
                "description": "Command whose nonzero exit stopped launch preparation."
              },
              "exit_code": {
                "type": "integer",
                "description": "Exit code of the failed command, or of the process that exited before its port listened."
              },
              "stderr_tail": {
                "type": "string",
                "description": "At most the final 4 KiB of stderr from the failed command, with resolved secret values\nredacted. port_not_listening carries the same tail of the process's stderr.\n"
              },
              "stdout_tail": {
                "type": "string",
                "description": "port_not_listening only; at most the final 4 KiB of the process's stdout."
              },
              "agent": {
                "type": "string",
                "description": "Unknown catalog agent name."
              },
              "port": {
                "type": "integer",
                "minimum": 1,
                "maximum": 65535,
                "description": "The sandbox port whose preview was refused (preview_access_refused) or that never accepted connections (port_not_listening)."
              },
              "revoked": {
                "type": "boolean",
                "description": "preview_access_refused only; true when the unwanted preview was ended and no\naccess to the port remains. False: it may still be reachable (outcome unknown).\n"
              },
              "preview_id": {
                "type": "string",
                "description": "preview_access_refused only; the identifier the provider gave the preview that may\nstill be reachable. Present only for a public preview.\n"
              },
              "url": {
                "type": "string",
                "format": "uri",
                "description": "preview_access_refused only; the address of a public preview that may still be\nreachable. Never present for a private preview, whose address holds a credential,\nand never when it was ended.\n"
              }
            }
          },
          "request_id": {
            "type": "string"
          },
          "doc_url": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri",
            "description": "Where the documentation explains this code: `https://boxrouter.ai/docs/error-codes#` followed by the code, for example `https://boxrouter.ai/docs/error-codes#no_eligible_route`. The page has one anchored row per code with what it means and what to do. BoxRouter sends it with every error; it is null for a code that has no documented row. Clients must accept an error body that omits it."
          },
          "fix": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "description": "Actionable change for the caller when the request cannot be completed. A refusal (4xx) always carries one; a server or provider fault, including an error event that ends a terminal or process stream, can answer null."
          },
          "operation_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Durable server operation ID for reconciliation after uncertain mutations."
          },
          "outcome": {
            "type": "string",
            "enum": [
              "not_started",
              "completed",
              "partial",
              "unknown"
            ],
            "description": "What is known about the requested side effect. `not_started` means nothing ran\nanywhere, at BoxRouter or at a provider; a launch-setup or process-start failure\nafter dispatch is `partial` or `unknown`. Unknown and partial forbid automatic\nreplay and always carry `retry: check_outcome`. An HTTP status alone does not establish\noutcome.\nMany refusals report not_started before the provider is asked anything. A read\n(GET or HEAD) has no side effect to be unsure about, so its failures report\nnot_started and carry the code's own retry value. A launch preparation failure\nhappens after the sandbox was created and setup commands may already have run, and\ndeleting the sandbox does not undo effects outside it: it reports partial once the\ncleanup is confirmed and unknown if it is not. A process that wait_for_port ended\nreports partial. volume_restore_failed on a resume or create,\nand volume_save_failed after the guest was read, report unknown or partial; they\ncarry the operation_id when the call was recorded, and their fix does not offer to\nsend the call again unchanged.\n"
          },
          "retry": {
            "type": "string",
            "enum": [
              "safe",
              "after_fix",
              "check_outcome",
              "never"
            ],
            "x-boxrouter-open-enum": true,
            "description": "What the caller may do next, fixed per code (x-boxrouter-error-retry): safe resends the\nsame request, after_fix changes the request or setup first, check_outcome reads\n`outcome` and the resource before resending, never does not resend. Branch on this\ninstead of the HTTP status.\n"
          },
          "retry_after_seconds": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0,
            "description": "How long to wait before a `retry: safe` resend, as the Retry-After header says it; null when there is no wait to name."
          },
          "provider": {
            "type": [
              "string",
              "null"
            ]
          },
          "native_code": {
            "type": [
              "string",
              "null"
            ],
            "description": "The provider's machine-readable error code, unchanged, when it reports one."
          },
          "native_status": {
            "type": [
              "integer",
              "null"
            ],
            "description": "The provider's HTTP status, unchanged, when the failure came from a provider response."
          },
          "native_message": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 4096,
            "description": "The provider's own error message when it answered with an HTTP 4xx refusal (for example a plan limit); null otherwise. Capped at 512 characters, with whitespace collapsed. Credential secrets and token-shaped strings are removed before return. The literal `[redacted]` marker is used when all credential secret fields are at least 12 characters; legacy saved secrets shorter than 12 characters are removed without the marker."
          }
        }
      },
      "SandboxTerminalInput": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "data_base64"
        ],
        "properties": {
          "data_base64": {
            "type": "string",
            "contentEncoding": "base64",
            "maxLength": 87384,
            "description": "Canonical base64 of at most 65536 exact bytes. No newline is appended."
          }
        }
      },
      "SandboxTerminalSize": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "columns": {
            "x-boxrouter-input-error": "Terminal columns must be an integer from 1 to 1000",
            "type": "integer",
            "minimum": 1,
            "maximum": 1000,
            "default": 80
          },
          "rows": {
            "x-boxrouter-input-error": "Terminal rows must be an integer from 1 to 1000",
            "type": "integer",
            "minimum": 1,
            "maximum": 1000,
            "default": 24
          }
        }
      },
      "SecretList": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "secrets"
        ],
        "properties": {
          "secrets": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Secret"
            }
          }
        }
      },
      "Secret": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "name",
          "created_at",
          "updated_at"
        ],
        "properties": {
          "name": {
            "$ref": "#/components/schemas/SecretName"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "PutSecret": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "value"
        ],
        "properties": {
          "value": {
            "type": "string",
            "maxLength": 16384,
            "pattern": "^[^\\u0000]*$",
            "writeOnly": true,
            "description": "Secret value. It is never returned, logged or included in an error response."
          }
        }
      },
      "PreviewPage": {
        "type": "object",
        "required": [
          "data",
          "next_cursor"
        ],
        "description": "The previews one sandbox has open, recorded by BoxRouter and read without observing any provider.",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Preview"
            }
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "Preview": {
        "type": "object",
        "required": [
          "id",
          "port",
          "url",
          "access",
          "credential",
          "headers",
          "expires_at",
          "created_at"
        ],
        "description": "One open preview, as BoxRouter recorded it. A resume forgets a sandbox's previews,\nbecause no adapter can re-read one: open again rather than caching a URL.\n",
        "properties": {
          "id": {
            "type": "string",
            "description": "BoxRouter's own ID, prefixed pv_, which a revoke names."
          },
          "port": {
            "type": "integer",
            "minimum": 1,
            "maximum": 65535
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "access": {
            "type": "string",
            "enum": [
              "public",
              "private"
            ]
          },
          "credential": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "link",
              "header",
              null
            ],
            "description": "Where a private preview's credential is: link, in the url, which a person can\nclick; header, in headers, to send with every request. Null for a public one.\n"
          },
          "headers": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "Credential headers to send with every request; empty unless credential is header."
          },
          "expires_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "Set only where the provider enforces an expiry, and never sooner than a granted\nlink_lifetime_seconds after created_at. There is no way to shorten a link (D30).\n"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "OpenPreview": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "port"
        ],
        "description": "A preview request for one port declared by the sandbox's previews requirement.\n",
        "properties": {
          "port": {
            "type": "integer",
            "minimum": 1,
            "maximum": 65535,
            "description": "Must be one of the gate's ports, else not_named."
          },
          "access": {
            "type": "string",
            "enum": [
              "public",
              "private"
            ],
            "description": "Which kind of link to open. Required only when granted.access holds both values,\nand not allowed when the request named \"any\": then the result says which it is.\n"
          },
          "credential": {
            "type": "string",
            "enum": [
              "link",
              "header"
            ],
            "description": "Where a private preview carries its credential, and only with access private.\nLeft out, the adapter picks and the result says which.\n"
          }
        }
      },
      "Browser": {
        "type": "object",
        "required": [
          "automation",
          "version",
          "executable"
        ],
        "properties": {
          "automation": {
            "type": "array",
            "minItems": 1,
            "items": {
              "type": "string",
              "enum": [
                "playwright",
                "cdp"
              ]
            },
            "description": "Channels that loaded a page served inside the guest."
          },
          "version": {
            "type": "string"
          },
          "executable": {
            "type": "string"
          }
        }
      },
      "Paused": {
        "type": "object",
        "required": [
          "state",
          "keeps",
          "outside_grant",
          "lifetime"
        ],
        "properties": {
          "state": {
            "type": "string",
            "enum": [
              "paused"
            ]
          },
          "keeps": {
            "type": "string",
            "enum": [
              "files_only",
              "files_and_memory"
            ]
          },
          "outside_grant": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "keeps"
              ]
            },
            "description": "Observed values that fell outside the pause_resume grant."
          },
          "lifetime": {
            "$ref": "#/components/schemas/Lifetime"
          },
          "pause_expires_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "Deadline after which a managed paused sandbox is terminated; null when no managed pause deadline applies."
          }
        }
      },
      "Lifetime": {
        "type": "object",
        "required": [
          "seconds",
          "remaining_seconds",
          "ends_at",
          "kept_until",
          "at_end",
          "max_seconds",
          "extendable"
        ],
        "description": "How long the sandbox may live. It counts from the provider's create, as with the\nprovider's own SDK (BoxRouter's clock starts when it sends the create). Whether paused\ntime counts depends on the provider.\n",
        "properties": {
          "seconds": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0,
            "description": "The lifetime in seconds. 0 only for a sandbox that has no lifetime record (one that\nended before lifetimes were recorded). Null for a sandbox created with no lifetime\n(`lifetime_seconds: null`), which runs until it is destroyed.\n"
          },
          "remaining_seconds": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0,
            "description": "As of observed_at. Equal to seconds while creating, and frozen while the sandbox is not\nrunning. Null for a sandbox with no lifetime.\n"
          },
          "ends_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "Set only while running. The end never comes before it; how soon after is not\npromised. Null while creating, paused or ended, and for a sandbox with no lifetime.\n"
          },
          "kept_until": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "While paused: when the sandbox is destroyed if it is not resumed, 30\ndays after it last ran, sooner where the provider keeps it for less. Where the lifetime\nkeeps counting while paused, the sandbox ends when the lifetime runs out, so\nkept_until is that moment when it falls inside the 30 days; extending the lifetime\nmoves it. Where the clock stops while paused, the full 30 days apply.\n"
          },
          "at_end": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "destroy",
              "pause",
              null
            ],
            "description": "What happens when the lifetime is used up. Null for a sandbox with no lifetime."
          },
          "max_seconds": {
            "description": "The route's longest single run, from one start to the next pause or end, as\nnarrowed for this account. A declared number: an integer, \"unlimited\", \"unknown\"\nor a floor.\n",
            "oneOf": [
              {
                "type": "integer",
                "minimum": 1
              },
              {
                "type": "string",
                "enum": [
                  "unlimited",
                  "unknown"
                ]
              },
              {
                "type": "object",
                "required": [
                  "at_least"
                ],
                "additionalProperties": false,
                "properties": {
                  "at_least": {
                    "type": "integer",
                    "minimum": 1
                  }
                }
              }
            ]
          },
          "extendable": {
            "type": "boolean"
          }
        }
      },
      "Resume": {
        "type": "object",
        "additionalProperties": false
      },
      "Resumed": {
        "type": "object",
        "required": [
          "state",
          "cold_restart",
          "outside_grant",
          "lifetime"
        ],
        "properties": {
          "state": {
            "type": "string",
            "enum": [
              "running"
            ]
          },
          "cold_restart": {
            "type": "boolean",
            "description": "Whether running processes were lost while the sandbox was paused or stopped."
          },
          "outside_grant": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "cold_restart"
              ]
            },
            "description": "Observed values that fell outside the pause_resume grant."
          },
          "lifetime": {
            "$ref": "#/components/schemas/Lifetime"
          }
        }
      },
      "UpdateNetworkPolicy": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "policy"
        ],
        "description": "The outbound policy to enforce from now on, with its entries. An allowlist needs at\nleast one allow entry and may carry deny entries, which win over its allow entries; a\ndenylist needs at least one deny entry and takes no allow entries; deny_all and open\ntake none.\n",
        "properties": {
          "policy": {
            "type": "string",
            "enum": [
              "deny_all",
              "allowlist",
              "denylist",
              "open"
            ]
          },
          "allow": {
            "type": "array",
            "maxItems": 4096,
            "items": {
              "$ref": "#/components/schemas/NetworkEntry"
            }
          },
          "deny": {
            "type": "array",
            "maxItems": 4096,
            "items": {
              "$ref": "#/components/schemas/NetworkEntry"
            }
          }
        },
        "allOf": [
          {
            "if": {
              "properties": {
                "policy": {
                  "const": "allowlist"
                }
              },
              "required": [
                "policy"
              ]
            },
            "then": {
              "required": [
                "allow"
              ]
            }
          },
          {
            "if": {
              "properties": {
                "policy": {
                  "const": "denylist"
                }
              },
              "required": [
                "policy"
              ]
            },
            "then": {
              "required": [
                "deny"
              ],
              "not": {
                "required": [
                  "allow"
                ]
              }
            }
          },
          {
            "if": {
              "properties": {
                "policy": {
                  "enum": [
                    "deny_all",
                    "open"
                  ]
                }
              },
              "required": [
                "policy"
              ]
            },
            "then": {
              "not": {
                "anyOf": [
                  {
                    "required": [
                      "allow"
                    ]
                  },
                  {
                    "required": [
                      "deny"
                    ]
                  }
                ]
              }
            }
          }
        ]
      },
      "NetworkEntry": {
        "description": "A host name or address, or an HTTP rule object. A rule object needs the sandbox's\nnetwork_lockdown request to have named http_rules true.\n",
        "oneOf": [
          {
            "type": "string",
            "minLength": 1
          },
          {
            "$ref": "#/components/schemas/NetworkHttpRule"
          }
        ]
      },
      "NetworkHttpRule": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "hosts"
        ],
        "dependentRequired": {
          "paths": [
            "methods"
          ]
        },
        "description": "Requests to these hosts, optionally only these methods and paths. A matching allowlist\nrequest succeeds and other traffic to its hosts is refused; a matching denylist request is\nrefused and other traffic to its hosts succeeds.\n",
        "properties": {
          "hosts": {
            "type": "array",
            "minItems": 1,
            "uniqueItems": true,
            "items": {
              "type": "string",
              "minLength": 1
            },
            "description": "Host names, each once. An allowlist rule with methods names hosts without `*.`."
          },
          "methods": {
            "type": "array",
            "minItems": 1,
            "uniqueItems": true,
            "items": {
              "type": "string",
              "pattern": "^[!#$%&'*+.^_`|~0-9A-Z-]+$"
            },
            "description": "Upper-case HTTP methods, each once, or the single entry `ANY` for every method."
          },
          "paths": {
            "type": "array",
            "minItems": 1,
            "uniqueItems": true,
            "items": {
              "type": "string",
              "pattern": "^/"
            },
            "description": "Path globs starting with `/`; needs methods. `*` matches any run except `/`, `**` any\nrun including `/`; the whole path without its query string must match.\n"
          }
        }
      },
      "NetworkPolicyUpdated": {
        "type": "object",
        "required": [
          "policy"
        ],
        "properties": {
          "policy": {
            "type": "string",
            "enum": [
              "deny_all",
              "allowlist",
              "denylist",
              "open"
            ],
            "description": "The policy now enforced."
          }
        }
      },
      "ConnectProviderAccount": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "name",
          "credentials"
        ],
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100,
            "pattern": "^[^\\u0000]*$"
          },
          "credentials": {
            "$ref": "#/components/schemas/Credentials"
          }
        }
      },
      "Credentials": {
        "description": "One provider's account credentials as flat fields. `provider` names an available\nprovider (`available_providers` of listProviderAccounts); every other property is one of\nthat provider's `credential_fields`. A required field is a nonempty string; an optional\nfield is a string or null, and null is the same as leaving it out. Secret values contain\n12 through 16384 characters and identifiers 1 through 256. A field the provider does not\ndeclare, a missing or null required field, or a value of another type is rejected; errors\nname the field, never its value. Accepted only on credential-management endpoints, over\nTLS. Write-only and encrypted at rest. Never logged or returned.\n",
        "type": "object",
        "required": [
          "provider"
        ],
        "maxProperties": 9,
        "propertyNames": {
          "pattern": "^[a-z][a-z0-9_]{0,63}$"
        },
        "properties": {
          "provider": {
            "type": "string",
            "minLength": 1,
            "maxLength": 64
          }
        },
        "additionalProperties": {
          "type": [
            "string",
            "null"
          ],
          "minLength": 1,
          "maxLength": 16384,
          "writeOnly": true
        }
      },
      "ProviderAccount": {
        "type": "object",
        "required": [
          "id",
          "name",
          "provider",
          "status",
          "credential_version",
          "settings"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "provider": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "description": "Known states are pending, enabled, invalid_credentials, credentials_rejected and unavailable.\nPending is a legacy state for an account saved before provider approval. Enabled means\nhosted BYOK is approved and the provider did not reject the credentials when they were saved.\ninvalid_credentials and unavailable remain readable for older records. credentials_rejected\nmeans a later provider call rejected the saved access; credential_failure gives a safe cause\nand the action needed to restore it.\n"
          },
          "settings": {
            "description": "Non-secret credential fields saved with the credentials, named as in credential_fields. Legacy accounts may return an empty object. Secrets are never returned; credential_hints may return the last four characters and credential_prefixes only a declared public prefix.",
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "credential_version": {
            "type": "integer",
            "minimum": 1,
            "description": "Monotonic version. Contains no key material or key fingerprint; credential_hints and credential_prefixes may return only the last four characters and a declared public prefix, respectively."
          },
          "credential_hints": {
            "type": "object",
            "description": "Last four characters of saved secret credential fields that contain at least 12 characters. No other key material is returned.",
            "additionalProperties": {
              "type": "string",
              "pattern": "^.{4}$"
            }
          },
          "credential_prefixes": {
            "type": "object",
            "description": "Declared public prefixes for saved secret credential fields, returned only when the saved value starts with the declared prefix and at least eight characters remain hidden before the last four. No other key material is returned.",
            "additionalProperties": {
              "type": "string",
              "pattern": "^[a-z0-9]{2,8}[_-]$"
            }
          },
          "credential_failure": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/ProviderCredentialFailure"
              },
              {
                "type": "null"
              }
            ],
            "description": "Present when a later provider call rejected the saved credentials or access."
          },
          "standard_image": {
            "$ref": "#/components/schemas/ProviderStandardImage"
          },
          "disconnect": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/ProviderAccountDisconnect"
              },
              {
                "type": "null"
              }
            ],
            "description": "A removal accepted with `wait=false` that is still running or was refused; null otherwise."
          },
          "warnings": {
            "type": "array",
            "description": "Notices about this connect. Present only on the response that created the account, and\nonly when there is something to say.\n",
            "items": {
              "$ref": "#/components/schemas/ProviderAccountWarning"
            }
          }
        }
      },
      "ProviderCredentialFailure": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "state",
          "status",
          "cause",
          "remedy",
          "detected_at"
        ],
        "properties": {
          "state": {
            "type": "string",
            "const": "credentials_rejected"
          },
          "status": {
            "type": "integer",
            "enum": [
              401,
              403
            ],
            "description": "Provider HTTP status returned by the rejected call."
          },
          "cause": {
            "type": "string",
            "enum": [
              "provider_rejected_credentials",
              "provider_access_denied"
            ],
            "x-boxrouter-open-enum": true,
            "description": "Safe normalized cause; provider response bodies and credential values are excluded."
          },
          "remedy": {
            "type": "string",
            "minLength": 1,
            "description": "The action needed to restore access, based on the provider and HTTP status."
          },
          "detected_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "ProviderStandardImage": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "state",
          "region",
          "image_version",
          "image_digest",
          "reason",
          "fix",
          "checked_at"
        ],
        "oneOf": [
          {
            "properties": {
              "state": {
                "const": "ready"
              },
              "reason": {
                "type": "null"
              },
              "fix": {
                "type": "null"
              }
            },
            "required": [
              "state",
              "reason",
              "fix"
            ]
          },
          {
            "properties": {
              "state": {
                "const": "preparing"
              },
              "reason": {
                "type": "null"
              },
              "fix": {
                "type": "null"
              }
            },
            "required": [
              "state",
              "reason",
              "fix"
            ]
          },
          {
            "properties": {
              "state": {
                "const": "failed"
              },
              "reason": {
                "type": "string",
                "minLength": 1
              },
              "fix": {
                "type": "string",
                "minLength": 1
              }
            },
            "required": [
              "state",
              "reason",
              "fix"
            ]
          },
          {
            "properties": {
              "state": {
                "const": "unavailable"
              },
              "fix": {
                "type": "string",
                "minLength": 1
              }
            },
            "required": [
              "state"
            ]
          }
        ],
        "properties": {
          "state": {
            "type": "string",
            "enum": [
              "ready",
              "preparing",
              "failed",
              "unavailable"
            ]
          },
          "region": {
            "type": "string"
          },
          "image_version": {
            "type": "string"
          },
          "image_digest": {
            "type": "string"
          },
          "reason": {
            "type": [
              "string",
              "null"
            ],
            "description": "Provider's reason when setup failed, or the reason this account cannot use the standard image."
          },
          "fix": {
            "type": [
              "string",
              "null"
            ],
            "description": "The one action needed to establish readiness or recover from a failed setup."
          },
          "checked_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        }
      },
      "ProviderAccountDisconnect": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "state",
          "started_at",
          "finished_at",
          "error"
        ],
        "description": "Progress of a removal accepted with `wait=false`. A finished removal leaves no account\n(404), so there is no completed state. A removal still disconnecting ten minutes after\nit started was stopped with its server and reads as failed; remove the account again.\n",
        "properties": {
          "state": {
            "type": "string",
            "enum": [
              "disconnecting",
              "failed"
            ],
            "x-boxrouter-open-enum": true
          },
          "started_at": {
            "type": "string",
            "format": "date-time"
          },
          "finished_at": {
            "oneOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ]
          },
          "error": {
            "description": "Present when state is failed. The same code, message and fix the synchronous request returns as its refusal.",
            "oneOf": [
              {
                "$ref": "#/components/schemas/ProviderAccountDisconnectError"
              },
              {
                "type": "null"
              }
            ]
          }
        }
      },
      "ProviderAccountDisconnectError": {
        "type": "object",
        "required": [
          "code",
          "message",
          "fix",
          "request_id",
          "details"
        ],
        "properties": {
          "code": {
            "type": "string"
          },
          "message": {
            "type": "string"
          },
          "fix": {
            "type": [
              "string",
              "null"
            ]
          },
          "request_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "The removal request's ID."
          },
          "details": {
            "type": "object",
            "description": "Code-specific context, such as `sandbox_ids` naming the live sandboxes in the way."
          }
        }
      },
      "ProviderAccountWarning": {
        "type": "object",
        "required": [
          "code",
          "message"
        ],
        "properties": {
          "code": {
            "type": "string",
            "enum": [
              "duplicate_credential"
            ],
            "x-boxrouter-open-enum": true,
            "description": "duplicate_credential: another account of this workspace has the same provider, settings\nand last four characters of every secret. New values may appear.\n"
          },
          "message": {
            "type": "string",
            "description": "What was noticed and what to do about it."
          },
          "account_id": {
            "type": "string",
            "description": "The other account the notice is about."
          }
        }
      },
      "ProviderAccountPage": {
        "type": "object",
        "required": [
          "data",
          "next_cursor",
          "available_providers",
          "credential_fields"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ProviderAccount"
            }
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ]
          },
          "available_providers": {
            "description": "Providers this deployment currently enables for saving, testing and using accounts. Independent of this page's account rows.",
            "type": "array",
            "uniqueItems": true,
            "items": {
              "type": "string"
            }
          },
          "provider_metadata": {
            "description": "Public, static presentation metadata keyed by provider ID. This does not indicate whether the provider is approved; use available_providers for that.",
            "type": "object",
            "additionalProperties": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "display_name"
              ],
              "properties": {
                "display_name": {
                  "type": "string"
                },
                "credential_help_url": {
                  "type": "string"
                }
              }
            }
          },
          "credential_fields": {
            "description": "The credential fields each available provider's connect, replace and test requests take, in the order the provider declares them.",
            "type": "object",
            "additionalProperties": {
              "type": "array",
              "items": {
                "$ref": "#/components/schemas/CredentialField"
              }
            }
          }
        }
      },
      "CredentialField": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "name",
          "secret",
          "required"
        ],
        "properties": {
          "name": {
            "type": "string",
            "pattern": "^[a-z][a-z0-9_]{0,63}$"
          },
          "label": {
            "type": "string",
            "description": "Public display label for this credential field."
          },
          "placeholder": {
            "type": "string",
            "description": "Static input hint; never a credential value or default."
          },
          "secret": {
            "type": "boolean",
            "description": "A secret is write-only; a saved one shows only in credential_hints and credential_prefixes."
          },
          "required": {
            "type": "boolean"
          }
        }
      },
      "TestProviderCredentials": {
        "description": "Supplied flat credential fields. No customer code runs, so a retried Test is safe\nand makes the same read-only provider request.\n",
        "type": "object",
        "additionalProperties": false,
        "required": [
          "credentials"
        ],
        "properties": {
          "credentials": {
            "$ref": "#/components/schemas/Credentials"
          }
        }
      },
      "ProviderAccountTest": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "ok",
          "native_status",
          "native_body"
        ],
        "properties": {
          "ok": {
            "type": "boolean"
          },
          "native_status": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Provider's native HTTP status; null when the protocol has no HTTP status."
          },
          "native_body": {
            "type": "string",
            "maxLength": 4096,
            "description": "Provider's response body, truncated to 4096 characters. Exact credential secret values are removed before the body is returned; partial or transformed values can remain. Review the response before sharing it. The literal `[redacted]` marker is used when all credential secret fields are at least 12 characters; legacy saved secrets shorter than 12 characters are removed without the marker."
          }
        }
      },
      "ReplaceCredentials": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "expected_version",
          "credentials"
        ],
        "properties": {
          "expected_version": {
            "type": "integer",
            "minimum": 1
          },
          "credentials": {
            "$ref": "#/components/schemas/Credentials"
          }
        }
      },
      "VolumePage": {
        "type": "object",
        "required": [
          "data",
          "next_cursor"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Volume"
            }
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ]
          },
          "stored_bytes": {
            "type": "integer",
            "minimum": 0,
            "description": "Current sum of stored bytes for ready retained checkpoints plus last observed disk usage for visible volumes. Not a billing amount."
          },
          "live_volume_policy": {
            "$ref": "#/components/schemas/LiveVolumePolicy",
            "description": "Present only when live storage is enabled and this workspace is allowlisted. Absence does not authorize live creation."
          },
          "allowance_bytes": {
            "type": "integer",
            "minimum": 0,
            "description": "The volume storage this workspace has included, in bytes. It is workspace configuration, so read it here instead of assuming a number. Storage within it is not charged."
          },
          "gib_hours_this_month": {
            "type": "number",
            "minimum": 0,
            "description": "GiB-hours of stored volume data over the completed UTC hours since the start of this month. Metered usage, not a billing amount."
          }
        }
      },
      "Volume": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "name",
          "state",
          "labels",
          "created_at",
          "updated_at",
          "last_used_at",
          "head_checkpoint",
          "checkpoint_count",
          "stored_bytes",
          "limits",
          "attachments"
        ],
        "description": "A durable folder stored by BoxRouter. Checkpoint and branch operations depend on current\ncapability admission. Its backend is internal.\n",
        "properties": {
          "id": {
            "$ref": "#/components/schemas/VolumeId"
          },
          "name": {
            "$ref": "#/components/schemas/VolumeName"
          },
          "state": {
            "type": "string",
            "enum": [
              "ready",
              "deleting"
            ],
            "x-boxrouter-open-enum": true,
            "description": "A deleting volume remains visible in GET and list results until remote removal is confirmed; after deletion GET returns 404 and the volume is omitted from list results."
          },
          "labels": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "observed_volume_bytes": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0,
            "description": "Last observed whole-volume disk usage, or null when unavailable. Not a checkpoint size or a billing amount."
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          },
          "last_used_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "Last attach or save; null before the first."
          },
          "head_checkpoint": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1,
            "description": "The checkpoint a new attachment restores by default; null while the volume is empty."
          },
          "checkpoint_count": {
            "type": "integer",
            "minimum": 0
          },
          "stored_bytes": {
            "type": "integer",
            "minimum": 0,
            "description": "Total stored bytes for this volume, or last observed whole-volume disk usage (zero before an observation). Prefer observed_volume_bytes, which distinguishes unknown from zero. Not a per-checkpoint size."
          },
          "limits": {
            "$ref": "#/components/schemas/VolumeLimits"
          },
          "attachments": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/VolumeAttachmentSummary"
            },
            "description": "All attachments, ordered by sandbox_id. Empty when unused."
          }
        }
      },
      "VolumeName": {
        "type": "string",
        "minLength": 1,
        "maxLength": 63,
        "pattern": "^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$"
      },
      "VolumeLimits": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "max_checkpoints"
        ],
        "properties": {
          "max_checkpoints": {
            "type": "integer",
            "minimum": 1,
            "description": "Maximum retained checkpoints; saving beyond it removes the oldest automatic (pause or destroy) checkpoint first, then the oldest saved one; the head is never removed."
          }
        }
      },
      "VolumeAttachmentSummary": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "sandbox_id",
          "access",
          "attached_at",
          "restored_checkpoint"
        ],
        "properties": {
          "sandbox_id": {
            "type": "string"
          },
          "access": {
            "type": "string",
            "enum": [
              "write",
              "read",
              "shared",
              "branch"
            ],
            "description": "Access mode recorded for this attachment."
          },
          "attached_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "restored_checkpoint": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1
          }
        }
      },
      "LiveVolumePolicy": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "enabled",
          "soft_quota_bytes"
        ],
        "properties": {
          "enabled": {
            "type": "boolean",
            "description": "Whether the deployment currently permits this allowlisted workspace to create live volumes. Route eligibility is checked separately at attachment."
          },
          "soft_quota_bytes": {
            "type": "integer",
            "minimum": 1,
            "description": "The most volume storage this workspace may hold, in bytes. Attach and save are refused with resource_limit (413) when observed usage is above it; writes already in progress are not stopped. It can be larger than allowance_bytes."
          }
        }
      },
      "CreateVolume": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "name"
        ],
        "properties": {
          "name": {
            "$ref": "#/components/schemas/VolumeName",
            "description": "Unique among the workspace's volumes that are not deleted."
          },
          "labels": {
            "type": "object",
            "maxProperties": 64,
            "propertyNames": {
              "maxLength": 63
            },
            "additionalProperties": {
              "type": "string",
              "maxLength": 255
            }
          }
        }
      },
      "VolumeCheckpointPage": {
        "type": "object",
        "required": [
          "data",
          "next_cursor"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/VolumeCheckpoint"
            }
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "VolumeCheckpoint": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "volume_id",
          "checkpoint",
          "state",
          "created_at",
          "reason",
          "saved_on",
          "image",
          "arch",
          "user",
          "path",
          "observed_volume_bytes",
          "duration_ms",
          "message"
        ],
        "description": "An immutable saved filesystem checkpoint identified by (volume_id, checkpoint). Observed\nvolume bytes are whole-disk measurements taken before the save, not per-checkpoint sizes.\nDeleting or expiring its API reference does not reclaim backend disk bytes; those remain\nuntil the volume is erased.\n",
        "properties": {
          "volume_id": {
            "$ref": "#/components/schemas/VolumeId"
          },
          "checkpoint": {
            "type": "integer",
            "minimum": 1
          },
          "state": {
            "type": "string",
            "enum": [
              "ready"
            ],
            "x-boxrouter-open-enum": true,
            "description": "Only committed checkpoints are listed; a save in progress is not a checkpoint."
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "reason": {
            "type": "string",
            "enum": [
              "requested",
              "destroy",
              "pause"
            ],
            "x-boxrouter-open-enum": true,
            "description": "requested is a save call; destroy and pause are saves BoxRouter made first."
          },
          "saved_on": {
            "$ref": "#/components/schemas/VolumeSavedOn"
          },
          "image": {
            "$ref": "#/components/schemas/VolumeImage"
          },
          "arch": {
            "type": "string",
            "enum": [
              "amd64",
              "arm64"
            ]
          },
          "user": {
            "$ref": "#/components/schemas/VolumeUser"
          },
          "path": {
            "type": "string",
            "pattern": "^/[^\\u0000]*$"
          },
          "observed_volume_bytes": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0,
            "description": "Whole-volume disk usage observed before this checkpoint was created. May include other retained checkpoints and concurrent writes; not an exact checkpoint size or billing amount."
          },
          "duration_ms": {
            "type": "integer",
            "minimum": 0,
            "description": "Save wall time measured by BoxRouter."
          },
          "message": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 500
          }
        }
      },
      "VolumeSavedOn": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "sandbox_id",
          "provider",
          "class",
          "region"
        ],
        "properties": {
          "sandbox_id": {
            "type": "string"
          },
          "provider": {
            "type": "string"
          },
          "class": {
            "type": [
              "string",
              "null"
            ]
          },
          "region": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "VolumeImage": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "value",
          "digest"
        ],
        "properties": {
          "value": {
            "type": "string",
            "description": "standard, the exact OCI reference the source sandbox was created with, or\n`prepared:sha256:<source>` for a provider-native artifact: the canonical SHA-256\nidentity of the resolved preparation source, so two account-native artifacts\nprepared from the same source carry one volume identity across providers.\n"
          },
          "digest": {
            "type": [
              "string",
              "null"
            ],
            "description": "The source OCI digest where BoxRouter knows it (always for standard). Null for a\nprepared artifact: its source key is not an OCI digest.\n"
          }
        }
      },
      "VolumeUser": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "name",
          "uid"
        ],
        "properties": {
          "name": {
            "type": "string"
          },
          "uid": {
            "type": "integer",
            "minimum": 0
          }
        }
      },
      "SaveVolume": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "sandbox_id": {
            "type": "string",
            "description": "The sandbox expected to hold the writer lease. If another sandbox holds it, or nobody\ndoes, the save is refused with volume_lease_lost. Omitted means the current holder.\nA mounted branch sandbox may also be named: the save is a ready checkpoint of that\nbranch's files. It does not advance the volume head or change the source volume, its\nbranch or its lease, so the next create without a checkpoint still restores the head.\nSelect the saved checkpoint number to reopen the branch's files. Read-only sandboxes\ncannot save, and a branch that is no longer mounted is refused with volume_lease_lost.\n"
          },
          "message": {
            "type": "string",
            "maxLength": 500
          }
        }
      },
      "CreateVolumeUpload": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "path",
          "size"
        ],
        "properties": {
          "path": {
            "$ref": "#/components/schemas/VolumeFilePath"
          },
          "size": {
            "type": "integer",
            "minimum": 0,
            "maximum": 5497558138880,
            "description": "File size in bytes, from zero through 5 TiB. Even an empty file uses one multipart part."
          }
        }
      },
      "VolumeFilePath": {
        "type": "string",
        "minLength": 1,
        "maxLength": 1024,
        "pattern": "^(?!/)(?!.*//)(?!\\.{1,2}(?:/|$))(?!.*\\/\\.{1,2}(?:/|$))(?!.*\\u0000).+$",
        "description": "Relative path from the volume root, visible in sandboxes at `/workspace/<path>`.\nEmpty paths, a leading slash, empty, `.` or `..` segments, NUL, and paths longer\nthan 1024 UTF-8 bytes are refused with `invalid_request` (400).\n"
      },
      "VolumeUpload": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "volume_id",
          "path",
          "size",
          "part_size",
          "parts",
          "expires_at"
        ],
        "description": "Multipart upload session. Upload each part URL with an HTTP PUT containing exactly\nthe part bytes, then pass each response ETag header to complete. Part URLs and this\nsession expire together, six hours after creation plus about one hour for each 70 GiB of the\ndeclared size, at most 72 hours. The file appears at `/workspace/<path>` in\nsandboxes after completion. An open upload blocks write sandboxes; write attachments\nblock creating uploads. Read and shared sandboxes may need to refresh their volume\ncache to see the new file.\n",
        "properties": {
          "id": {
            "$ref": "#/components/schemas/UploadId"
          },
          "volume_id": {
            "$ref": "#/components/schemas/VolumeId"
          },
          "path": {
            "$ref": "#/components/schemas/VolumeFilePath"
          },
          "size": {
            "type": "integer",
            "minimum": 0,
            "maximum": 5497558138880
          },
          "part_size": {
            "type": "integer",
            "minimum": 1
          },
          "parts": {
            "type": "array",
            "minItems": 1,
            "maxItems": 10000,
            "items": {
              "$ref": "#/components/schemas/VolumeUploadPart"
            }
          },
          "expires_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "UploadId": {
        "type": "string",
        "pattern": "^vup_[0-9a-f]{32}$"
      },
      "VolumeUploadPart": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "number",
          "size",
          "url"
        ],
        "properties": {
          "number": {
            "type": "integer",
            "minimum": 1,
            "maximum": 10000
          },
          "size": {
            "type": "integer",
            "minimum": 0
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "Temporary URL to PUT exactly this part's bytes. The response ETag header is required to complete the upload."
          }
        }
      },
      "CompleteVolumeUpload": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "parts"
        ],
        "properties": {
          "parts": {
            "type": "array",
            "minItems": 1,
            "maxItems": 10000,
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "number",
                "etag"
              ],
              "properties": {
                "number": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 10000
                },
                "etag": {
                  "type": "string",
                  "minLength": 1
                }
              }
            }
          }
        }
      },
      "CompletedVolumeUpload": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "path",
          "size"
        ],
        "properties": {
          "path": {
            "$ref": "#/components/schemas/VolumeFilePath"
          },
          "size": {
            "type": "integer",
            "minimum": 0,
            "maximum": 5497558138880
          }
        }
      },
      "CreateVolumeDownload": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "path"
        ],
        "properties": {
          "path": {
            "$ref": "#/components/schemas/VolumeFilePath"
          }
        }
      },
      "VolumeDownload": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "url",
          "path",
          "size",
          "expires_at"
        ],
        "description": "Temporary link to a volume file; the URL expires one hour after creation.",
        "properties": {
          "url": {
            "type": "string",
            "format": "uri"
          },
          "path": {
            "$ref": "#/components/schemas/VolumeFilePath"
          },
          "size": {
            "type": "integer",
            "minimum": 0
          },
          "expires_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "VolumeFilePrefix": {
        "type": "string",
        "maxLength": 1024,
        "pattern": "^(?!/)(?!.*//)(?!\\.{1,2}(?:/|$))(?!.*\\/\\.{1,2}(?:/|$))(?!.*\\u0000).*$",
        "description": "Relative volume path prefix; may be empty or end in `/`, but follows the same path safety rules as VolumeFilePath."
      },
      "VolumeFilePage": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "data",
          "next_cursor"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/VolumeFile"
            }
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "VolumeFile": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "path",
          "size",
          "modified_at"
        ],
        "properties": {
          "path": {
            "$ref": "#/components/schemas/VolumeFilePath"
          },
          "size": {
            "type": "integer",
            "minimum": 0
          },
          "modified_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "Sandbox": {
        "type": "object",
        "description": "A sandbox created from a settled body, returned by create, restore, get and list.\nRequired fields are present; fields with no value are null, never absent. Optional\nfields may be absent when their source is not known. Listings do no\nprovider I/O: they show the latest durably recorded state, and native_state,\nroute.selection and recorder are null. Detail responses observe the provider live and\nrecord the normalized state unless a concurrent lifecycle change supersedes the read.\n",
        "required": [
          "id",
          "state",
          "state_reason",
          "failure",
          "native_state",
          "observed_at",
          "state_recorded_at",
          "created_at",
          "ready_at",
          "ended_at",
          "labels",
          "lifetime",
          "route",
          "contract",
          "request",
          "hidden_secrets",
          "tcp_ports",
          "recorder",
          "limits"
        ],
        "properties": {
          "id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128,
            "pattern": "^[^\\u0000]*$"
          },
          "state": {
            "type": "string",
            "enum": [
              "creating",
              "running",
              "paused",
              "destroying",
              "destroyed",
              "error",
              "unknown"
            ],
            "x-boxrouter-open-enum": true,
            "description": "Clients must tolerate values they do not know. A sandbox the provider stopped, or one\nstopped for being idle that can be started again, reads paused; resume brings either back.\n"
          },
          "state_reason": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "requested",
              "lifetime",
              "retention",
              "idle_shutdown",
              "external",
              null
            ],
            "x-boxrouter-open-enum": true,
            "description": "Why it is in this state. external is a change made at the provider, behind BoxRouter's back."
          },
          "failure": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/SandboxFailure"
              },
              {
                "type": "null"
              }
            ],
            "description": "The provider failure recorded with state=error, or null when no recorded failure\nexplains the current state. Present on create, detail and list responses; list\nreads return the durable value without calling the provider.\n"
          },
          "native_state": {
            "type": [
              "string",
              "null"
            ]
          },
          "observed_at": {
            "type": "string",
            "format": "date-time",
            "description": "Time the state source for this response was read: the owned-record lookup time\nfor a list response, or the live provider-observation time for a detail response.\n"
          },
          "state_recorded_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "Timestamp of the durable state source used for this response. This can be an\nexisting lifecycle or lifetime record when the returned public state is derived\nfrom that source, and may predate observed_at. Null when no source timestamp is\navailable or a concurrent lifecycle change supersedes the detail read.\n"
          },
          "created_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "Time Cloud sent the first create request when that edge is available; otherwise the sandbox record's created time."
          },
          "expires_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "Enforced deadline from the recorded lifetime budget, including extensions. This\nis the same deadline exposed as lifetime.ends_at; null when no deadline is known.\n"
          },
          "ready_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "Time Cloud received the first create response; when that edge is unavailable, the sandbox\nrecord's ready time. Null while creating. List and detail responses use the same value.\n"
          },
          "ended_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "Time Cloud received the last destroy response; when that edge is unavailable, Cloud's\nrecord of confirmation or first observation that the sandbox was gone. Null while the\nsandbox has not ended. List and detail responses use the same value.\n"
          },
          "created_at_source": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/UsageSource"
              },
              {
                "type": "null"
              }
            ],
            "description": "Where `created_at` came from. Null when `created_at` is null. Always BoxRouter's own record."
          },
          "created_at_how": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "description": "One sentence saying how `created_at` was determined. Null when `created_at` is null."
          },
          "created_at_step": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1,
            "description": "Null because `created_at` comes from a recorded lifecycle edge or Cloud's record."
          },
          "ready_at_source": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/UsageSource"
              },
              {
                "type": "null"
              }
            ],
            "description": "Where `ready_at` came from. Null when `ready_at` is null. Lifecycle edges and Cloud's own record are `recorded`."
          },
          "ready_at_how": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "description": "One sentence saying how `ready_at` was determined. Null when `ready_at` is null."
          },
          "ready_at_step": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1,
            "description": "Null because `ready_at` comes from a recorded lifecycle edge or Cloud's record."
          },
          "ended_at_source": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/UsageSource"
              },
              {
                "type": "null"
              }
            ],
            "description": "Where `ended_at` came from. Null when `ended_at` is null. Lifecycle edges and Cloud's own record are `recorded`."
          },
          "ended_at_how": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "description": "One sentence saying how `ended_at` was determined. Null when `ended_at` is null."
          },
          "ended_at_step": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1,
            "description": "Null because `ended_at` comes from a recorded lifecycle edge or Cloud's record."
          },
          "cost_source": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/UsageSource"
              },
              {
                "type": "null"
              }
            ],
            "description": "Where `cost` came from. Null when `cost` is null. `provider` for a reported cost, `calculated` for a worked-out one, `unknown` when no cost could be worked out. The `cost_step` is 1 for a provider figure, then 2 provider times, 3 a checked billing boundary, 4 a range, 5 unknown."
          },
          "cost_how": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "description": "One sentence saying how `cost` was determined. Null when `cost` is null."
          },
          "cost_step": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1,
            "description": "The position of the source in BoxRouter's source order for this value, 1 being the best.\nNull when the value is BoxRouter's own record rather than a pick between sources.\n"
          },
          "origin": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/SandboxOrigin"
              },
              {
                "type": "null"
              }
            ],
            "description": "Durable creation provenance. Omitted when the source is not known."
          },
          "labels": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Sandbox name from labels.name, when set."
          },
          "resources": {
            "type": "object",
            "description": "Resolved CPU, memory and disk resources; null values mean unknown.",
            "properties": {
              "cpu": {
                "type": [
                  "number",
                  "null"
                ],
                "exclusiveMinimum": 0
              },
              "memory_mib": {
                "type": [
                  "integer",
                  "null"
                ],
                "minimum": 1
              },
              "disk_mib": {
                "type": [
                  "integer",
                  "null"
                ],
                "minimum": 1
              }
            }
          },
          "image": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/SandboxImage"
              },
              {
                "type": "null"
              }
            ],
            "description": "The image the sandbox runs and where that is known from. Null when nothing records\nit. Absent from responses of a Cloud that does not report it yet.\n"
          },
          "image_setup": {
            "$ref": "#/components/schemas/SandboxImageSetup",
            "description": "Present only when this start waited for image setup on its chosen provider."
          },
          "usage": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Usage"
              },
              {
                "$ref": "#/components/schemas/LegacyZeroGpuUsage"
              },
              {
                "type": "null"
              }
            ],
            "description": "What the sandbox used: its size, its running time per state, how often it was created,\neach fact with the source it came from. Null when nothing has been recorded or the\nresponse does not carry it. Absent from responses of a Cloud that does not report it yet.\n"
          },
          "cost": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/Cost"
              },
              {
                "$ref": "#/components/schemas/SandboxCostSummary"
              },
              {
                "type": "null"
              }
            ],
            "description": "What the sandbox cost, with one word saying how far to trust it. Create and detail\nresponses carry the full cost with its working; list rows carry only its label and\ntotal, from the same calculation. One object serves both, so the schema accepts either\nshape anywhere: a client that needs the working reads the detail. Null when no cost has\nbeen worked out. Absent from responses of a Cloud that does not report it yet.\n"
          },
          "charge": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/SandboxCharge"
              },
              {
                "type": "null"
              }
            ],
            "description": "What BoxRouter charged to the workspace's credits for this sandbox: the reservation\nwhile it runs, then the amount charged once the provider's records are in. Present\non credit-funded sandboxes in detail and list responses. Null for a sandbox paid with\nthe workspace's own provider account (BYOK), for a credit-funded one whose\nreservation was released without a charge, and for one whose ledger record cannot be\nverified: BoxRouter reports no charge rather than a guess. `cost` still reports the\nprovider's cost. Absent from create and other responses, and from a Cloud that does\nnot report it yet. It is the ledger's amount, never derived from `cost` or from\nBoxRouter's clock.\n"
          },
          "funded_until": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "The time up to which the workspace's credits are reserved for this sandbox. A sandbox\ncreated without `lifetime_seconds` renews its reservation hourly while the balance\ncovers it, so this moves later at each renewal; the sandbox ends at this time if the\nbalance could not cover another hour. For a sandbox created with `lifetime_seconds`\nit is the end of that lifetime. Null for a sandbox paid with the workspace's own\nprovider account (BYOK), which has no reservation. A reservation is a hold on the\nbalance, never a cost: `charge` reports the credits reserved and then charged. Present\non create and on detail and list reads; absent from a Cloud that does not report it yet.\n"
          },
          "connectable": {
            "type": "boolean",
            "description": "Whether interactive access to this sandbox is offered: a terminal, commands, files and\nprocesses. False for a sandbox an Actions job runs in, which holds that job's token and\nsecrets; Cloud refuses these operations on it, before and after the job ends, and the\ndashboard shows no Connect action. True for every other sandbox. One rule, decided by\nCloud; clients do not infer it from `origin`, which an Actions runner that has not yet\nserved a job does not have. Present on detail and list reads; absent from a Cloud that\ndoes not report it yet.\n"
          },
          "lifetime": {
            "$ref": "#/components/schemas/Lifetime"
          },
          "route": {
            "$ref": "#/components/schemas/SandboxRoute"
          },
          "contract": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/Contract"
              },
              {
                "type": "null"
              }
            ],
            "description": "Null for a record with no recorded contract, such as one a provider-native route created."
          },
          "request": {
            "$ref": "#/components/schemas/SandboxRequestSnapshot"
          },
          "hidden_secrets": {
            "type": [
              "object",
              "null"
            ],
            "propertyNames": {
              "$ref": "#/components/schemas/SecretName"
            },
            "additionalProperties": {
              "$ref": "#/components/schemas/HiddenSecretResult"
            },
            "description": "Public metadata for the request-only secret values, keyed by their submitted names.\nEach result contains only a placeholder and its allowed hosts. Null when the create\nsubmitted no secret values.\n"
          },
          "tcp_ports": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "$ref": "#/components/schemas/TcpPortEndpoint"
            },
            "description": "Public host and port for each requested TCP listener, in request order."
          },
          "recorder": {
            "type": [
              "object",
              "null"
            ],
            "description": "A tally of the gate calls made on this sandbox, allowed and refused, with the\nrequirements line those calls relied on. It only tallies: it switches no gate on.\n"
          },
          "limits": {
            "$ref": "#/components/schemas/SandboxLimits"
          },
          "volume": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/VolumeAttachment"
              },
              {
                "type": "null"
              }
            ],
            "description": "Present when the sandbox is attached to a BoxRouter Volume."
          },
          "operation_id": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "description": "Present on a destroy response: the workspace-owned destroy operation while lifecycle\nwork remains (`state` is `destroying`), null once the destroy is confirmed. Absent\nfrom every other response.\n"
          },
          "account": {
            "type": "object",
            "required": [
              "healthy",
              "detail"
            ],
            "description": "Present only while the account's key no longer works (section 7); that sandbox's\ncalls then answer account_unhealthy and state is unknown.\n",
            "properties": {
              "healthy": {
                "type": "boolean"
              },
              "detail": {
                "type": [
                  "string",
                  "null"
                ]
              }
            }
          }
        }
      },
      "SandboxFailure": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "summary",
          "provider_state",
          "native_code",
          "native_message",
          "observed_at"
        ],
        "description": "The most recent provider failure recorded with the sandbox's state. The summary is\nBoxRouter-authored plain language. `provider_state` is the raw provider status\nand is not covered by the sanitization guarantee; `native_code` and\n`native_message` contain only allowlisted, sanitized values. Repeated observations of the same failure keep the first\nobserved_at; a changed failure gets a new timestamp. This object is stored with\nthe state, cleared when the sandbox leaves error, and unchanged by unreadable\nprovider observations.\n",
        "properties": {
          "summary": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200,
            "description": "BoxRouter-authored plain language chosen from a fixed set keyed by provider and\nprovider_state. An unrecognised status uses \"The provider reported this sandbox\nas failed.\"; it never guesses a cause.\n"
          },
          "provider_state": {
            "type": [
              "string",
              "null"
            ],
            "description": "The provider's raw failure status, the same value native_state carries, or null if none was supplied."
          },
          "native_code": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^[A-Za-z0-9_.:-]{1,64}$",
            "description": "The provider's short structured failure code, or null if absent or unsafe."
          },
          "native_message": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 512,
            "description": "The provider's diagnostic text after redaction, or null if absent or unsafe."
          },
          "observed_at": {
            "type": "string",
            "format": "date-time",
            "description": "When BoxRouter first observed this specific failure."
          }
        }
      },
      "UsageSource": {
        "description": "Where a fact came from. provider: the provider's API told us, about this sandbox. published: the provider's docs or pricing page, not about this sandbox in particular. measured: BoxRouter checked it itself with a clock or in its own sandboxes. recorded: BoxRouter's own record of something it did or saw. calculated: worked out from other facts, each with its own source. unknown: nobody told us and we could not check.",
        "type": "string",
        "enum": [
          "provider",
          "published",
          "measured",
          "recorded",
          "calculated",
          "unknown"
        ]
      },
      "SandboxOrigin": {
        "description": "What created the sandbox, discriminated by source. github_actions is a BoxRouter\nActions job; agents is an agent launch (POST /launches). Sandboxes created directly\nthrough the API have no origin.\n",
        "oneOf": [
          {
            "$ref": "#/components/schemas/ActionsSandboxOrigin"
          },
          {
            "$ref": "#/components/schemas/AgentsSandboxOrigin"
          }
        ],
        "discriminator": {
          "propertyName": "source",
          "mapping": {
            "github_actions": "#/components/schemas/ActionsSandboxOrigin",
            "agents": "#/components/schemas/AgentsSandboxOrigin"
          }
        }
      },
      "ActionsSandboxOrigin": {
        "type": "object",
        "description": "A sandbox a BoxRouter Actions job ran in. source, run_id and job_id come from the\nplacement and are always present; every other fact is omitted when Cloud does not\nknow it.\n",
        "additionalProperties": false,
        "required": [
          "source",
          "run_id",
          "job_id"
        ],
        "properties": {
          "source": {
            "type": "string",
            "enum": [
              "github_actions"
            ]
          },
          "repository": {
            "type": "string",
            "minLength": 1,
            "description": "owner/name, from the job's GitHub webhook; for jobs admitted before the webhook was\nrecorded, from the workspace's GitHub repository binding for the same repository ID.\n"
          },
          "workflow": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "description": "Workflow name from the job's GitHub webhook or run."
          },
          "run_id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128,
            "pattern": "^[^\\u0000]*$",
            "description": "BoxRouter Actions run ID used by the Actions dashboard deep link."
          },
          "run_number": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1,
            "description": "GitHub run number from the run."
          },
          "job_id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128,
            "pattern": "^[^\\u0000]*$",
            "description": "BoxRouter Actions job ID."
          },
          "job_name": {
            "type": "string",
            "minLength": 1,
            "description": "Job name from the job's GitHub webhook."
          },
          "run_url": {
            "type": "string",
            "format": "uri",
            "description": "GitHub run page, built from repository and the GitHub run ID."
          },
          "job_url": {
            "type": "string",
            "format": "uri",
            "description": "GitHub job page: the job's html_url from its webhook, else built from repository and\nthe GitHub run and job IDs.\n"
          }
        }
      },
      "AgentsSandboxOrigin": {
        "type": "object",
        "description": "A sandbox created by an agent launch.",
        "additionalProperties": false,
        "required": [
          "source",
          "launch_id",
          "agent",
          "agent_name"
        ],
        "properties": {
          "source": {
            "type": "string",
            "enum": [
              "agents"
            ]
          },
          "launch_id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128,
            "pattern": "^[^\\u0000]*$",
            "description": "Launch operation ID, as in GET /launches/{operation_id}."
          },
          "agent": {
            "type": "string",
            "minLength": 1,
            "description": "The launched manifest's name; the agent catalog ID for catalog agents, such as claude-code."
          },
          "agent_name": {
            "type": "string",
            "minLength": 1,
            "description": "Display name from the agent catalog, such as Claude Code; the manifest name for agents outside the catalog."
          },
          "repository": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "description": "Repository as owner/name when the launch checked out code; null or absent when it had none."
          },
          "sha": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^[0-9a-f]{40}$",
            "description": "Commit checked out for the launch; null or absent when it had no code."
          }
        }
      },
      "SandboxImage": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "value",
          "source"
        ],
        "description": "The image a sandbox runs, with where that is known from: `recorded` for what the creation\nrequest asked for, `provider` where the provider reported which image or template it ran.\n",
        "properties": {
          "value": {
            "type": "string",
            "minLength": 1,
            "description": "`standard` when the request omitted `image` (BoxRouter's standard image), `provider_default`\nwhen it opted out, `dockerfile` for an image built from a Dockerfile, or else the OCI\nreference or provider artifact the request named.\n"
          },
          "source": {
            "$ref": "#/components/schemas/UsageSource"
          }
        }
      },
      "SandboxImageSetup": {
        "type": "object",
        "required": [
          "provider",
          "duration_ms"
        ],
        "properties": {
          "provider": {
            "type": "string",
            "minLength": 1
          },
          "duration_ms": {
            "type": "integer",
            "minimum": 0
          }
        }
      },
      "Usage": {
        "title": "Usage record",
        "description": "What one sandbox used, as a collector saw it. One record is one coherent set of inputs for the calculator; where two sources disagree, a collector builds one record per source. Every fact carries where it came from, when it was observed and how. A fact nobody could establish has source `unknown` and a null value; it is never left out or filled with a default. `provider`, the record's key, is the only value without provenance.",
        "type": "object",
        "additionalProperties": false,
        "required": [
          "provider",
          "started",
          "region",
          "size",
          "intervals",
          "creations"
        ],
        "properties": {
          "provider": {
            "description": "The provider that ran the sandbox, as named in its price versions.",
            "type": "string",
            "pattern": "^[a-z][a-z0-9-]*$"
          },
          "class": {
            "description": "The sandbox's class or runtime, which picks the rate set in the price version. If absent, it may be priced only when the price version has exactly one class; otherwise the cost is unknown.",
            "type": "object",
            "additionalProperties": false,
            "required": [
              "name",
              "source",
              "observed_at",
              "how"
            ],
            "properties": {
              "name": {
                "type": [
                  "string",
                  "null"
                ],
                "minLength": 1
              },
              "source": {
                "$ref": "#/components/schemas/UsageSource"
              },
              "observed_at": {
                "$ref": "#/components/schemas/PricingTimestamp"
              },
              "how": {
                "$ref": "#/components/schemas/UsageHow"
              }
            },
            "if": {
              "$ref": "#/components/schemas/UsageIsUnknown"
            },
            "then": {
              "properties": {
                "name": {
                  "type": "null"
                }
              }
            },
            "else": {
              "properties": {
                "name": {
                  "type": "string"
                }
              }
            }
          },
          "started": {
            "description": "When the sandbox started. It picks the price version in effect.",
            "type": "object",
            "additionalProperties": false,
            "required": [
              "at",
              "source",
              "observed_at",
              "how"
            ],
            "properties": {
              "at": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "source": {
                "$ref": "#/components/schemas/UsageSource"
              },
              "observed_at": {
                "$ref": "#/components/schemas/PricingTimestamp"
              },
              "how": {
                "$ref": "#/components/schemas/UsageHow"
              }
            },
            "if": {
              "$ref": "#/components/schemas/UsageIsUnknown"
            },
            "then": {
              "properties": {
                "at": {
                  "type": "null"
                }
              }
            },
            "else": {
              "properties": {
                "at": {
                  "$ref": "#/components/schemas/PricingTimestamp"
                }
              }
            }
          },
          "region": {
            "description": "The region the sandbox ran in, as the provider names it.",
            "type": "object",
            "additionalProperties": false,
            "required": [
              "name",
              "source",
              "observed_at",
              "how"
            ],
            "properties": {
              "name": {
                "type": [
                  "string",
                  "null"
                ],
                "minLength": 1
              },
              "source": {
                "$ref": "#/components/schemas/UsageSource"
              },
              "observed_at": {
                "$ref": "#/components/schemas/PricingTimestamp"
              },
              "how": {
                "$ref": "#/components/schemas/UsageHow"
              }
            },
            "if": {
              "$ref": "#/components/schemas/UsageIsUnknown"
            },
            "then": {
              "properties": {
                "name": {
                  "type": "null"
                }
              }
            },
            "else": {
              "properties": {
                "name": {
                  "type": "string"
                }
              }
            }
          },
          "size": {
            "description": "What the sandbox got. Each field is optional because a source may give only some of them; at least one is present unless the source is `unknown`. When GPUs are present, `gpu` and `gpu_model` are both recorded; without a GPU, both are absent.",
            "type": "object",
            "additionalProperties": false,
            "required": [
              "source",
              "observed_at",
              "how"
            ],
            "properties": {
              "cpu": {
                "description": "vCPUs.",
                "type": "number",
                "exclusiveMinimum": 0
              },
              "memory_mib": {
                "type": "integer",
                "minimum": 1
              },
              "disk_mib": {
                "type": "integer",
                "minimum": 1
              },
              "gpu": {
                "description": "Number of allocated GPUs.",
                "type": "integer",
                "minimum": 1
              },
              "gpu_model": {
                "description": "The allocated model's gpu-registry identifier.",
                "type": "string",
                "pattern": "^[a-z][a-z0-9-]*:[a-z0-9][a-z0-9-]*$"
              },
              "source": {
                "$ref": "#/components/schemas/UsageSource"
              },
              "observed_at": {
                "$ref": "#/components/schemas/PricingTimestamp"
              },
              "how": {
                "$ref": "#/components/schemas/UsageHow"
              }
            },
            "if": {
              "$ref": "#/components/schemas/UsageIsUnknown"
            },
            "then": {
              "not": {
                "anyOf": [
                  {
                    "required": [
                      "cpu"
                    ]
                  },
                  {
                    "required": [
                      "memory_mib"
                    ]
                  },
                  {
                    "required": [
                      "disk_mib"
                    ]
                  },
                  {
                    "required": [
                      "gpu"
                    ]
                  },
                  {
                    "required": [
                      "gpu_model"
                    ]
                  }
                ]
              }
            },
            "else": {
              "anyOf": [
                {
                  "required": [
                    "cpu"
                  ]
                },
                {
                  "required": [
                    "memory_mib"
                  ]
                },
                {
                  "required": [
                    "disk_mib"
                  ]
                },
                {
                  "required": [
                    "gpu"
                  ]
                }
              ]
            },
            "allOf": [
              {
                "if": {
                  "required": [
                    "gpu"
                  ]
                },
                "then": {
                  "required": [
                    "gpu_model"
                  ]
                }
              },
              {
                "if": {
                  "required": [
                    "gpu_model"
                  ]
                },
                "then": {
                  "required": [
                    "gpu"
                  ]
                }
              }
            ]
          },
          "intervals": {
            "description": "Time in each billed state, one entry per period, in time order. A price version's minimum and increment rules apply to each entry.",
            "type": "array",
            "minItems": 1,
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "state",
                "seconds",
                "source",
                "observed_at",
                "how"
              ],
              "properties": {
                "size": {
                  "$ref": "#/components/schemas/UsageSize"
                },
                "snapshot_storage": {
                  "$ref": "#/components/schemas/UsageSnapshotStorage"
                },
                "state": {
                  "enum": [
                    "running",
                    "paused",
                    "stopped"
                  ]
                },
                "seconds": {
                  "description": "Exact seconds, or a range when a change was noticed late and the period is only bounded.",
                  "oneOf": [
                    {
                      "type": "number",
                      "minimum": 0
                    },
                    {
                      "$ref": "#/components/schemas/UsageRange"
                    },
                    {
                      "type": "null"
                    }
                  ]
                },
                "source": {
                  "$ref": "#/components/schemas/UsageSource"
                },
                "observed_at": {
                  "$ref": "#/components/schemas/PricingTimestamp"
                },
                "how": {
                  "$ref": "#/components/schemas/UsageHow"
                }
              },
              "if": {
                "$ref": "#/components/schemas/UsageIsUnknown"
              },
              "then": {
                "properties": {
                  "seconds": {
                    "type": "null"
                  }
                }
              },
              "else": {
                "properties": {
                  "seconds": {
                    "type": [
                      "number",
                      "object"
                    ]
                  }
                }
              }
            }
          },
          "creations": {
            "description": "How many times the sandbox was created: 1, plus any restores that the provider charges as a creation.",
            "type": "object",
            "additionalProperties": false,
            "required": [
              "count",
              "source",
              "observed_at",
              "how"
            ],
            "properties": {
              "count": {
                "type": [
                  "integer",
                  "null"
                ],
                "minimum": 0
              },
              "source": {
                "$ref": "#/components/schemas/UsageSource"
              },
              "observed_at": {
                "$ref": "#/components/schemas/PricingTimestamp"
              },
              "how": {
                "$ref": "#/components/schemas/UsageHow"
              }
            },
            "if": {
              "$ref": "#/components/schemas/UsageIsUnknown"
            },
            "then": {
              "properties": {
                "count": {
                  "type": "null"
                }
              }
            },
            "else": {
              "properties": {
                "count": {
                  "type": "integer"
                }
              }
            }
          },
          "active_cpu": {
            "description": "Seconds of CPU the sandbox actually used, for providers that bill active CPU. Absent where the provider does not bill it.",
            "type": "object",
            "additionalProperties": false,
            "required": [
              "seconds",
              "source",
              "observed_at",
              "how"
            ],
            "properties": {
              "seconds": {
                "type": [
                  "number",
                  "null"
                ],
                "minimum": 0
              },
              "source": {
                "$ref": "#/components/schemas/UsageSource"
              },
              "observed_at": {
                "$ref": "#/components/schemas/PricingTimestamp"
              },
              "how": {
                "$ref": "#/components/schemas/UsageHow"
              }
            },
            "if": {
              "$ref": "#/components/schemas/UsageIsUnknown"
            },
            "then": {
              "properties": {
                "seconds": {
                  "type": "null"
                }
              }
            },
            "else": {
              "properties": {
                "seconds": {
                  "type": "number"
                }
              }
            }
          },
          "egress": {
            "description": "Bytes the sandbox sent out. Absent where the provider does not bill it.",
            "type": "object",
            "additionalProperties": false,
            "required": [
              "bytes",
              "source",
              "observed_at",
              "how"
            ],
            "properties": {
              "bytes": {
                "type": [
                  "integer",
                  "null"
                ],
                "minimum": 0
              },
              "source": {
                "$ref": "#/components/schemas/UsageSource"
              },
              "observed_at": {
                "$ref": "#/components/schemas/PricingTimestamp"
              },
              "how": {
                "$ref": "#/components/schemas/UsageHow"
              }
            },
            "if": {
              "$ref": "#/components/schemas/UsageIsUnknown"
            },
            "then": {
              "properties": {
                "bytes": {
                  "type": "null"
                }
              }
            },
            "else": {
              "properties": {
                "bytes": {
                  "type": "integer"
                }
              }
            }
          },
          "snapshot_storage": {
            "description": "The stored snapshot size, or its known maximum when the provider does not report the actual size.",
            "type": "object",
            "additionalProperties": false,
            "required": [
              "source",
              "observed_at",
              "how"
            ],
            "properties": {
              "gb": {
                "type": [
                  "number",
                  "null"
                ],
                "minimum": 0
              },
              "max_gb": {
                "type": [
                  "number",
                  "null"
                ],
                "minimum": 0
              },
              "source": {
                "$ref": "#/components/schemas/UsageSource"
              },
              "observed_at": {
                "$ref": "#/components/schemas/PricingTimestamp"
              },
              "how": {
                "$ref": "#/components/schemas/UsageHow"
              },
              "bytes": {
                "description": "Provider snapshot sizeBytes, kept as an exact integer.",
                "type": "integer",
                "minimum": 0
              }
            },
            "if": {
              "$ref": "#/components/schemas/UsageIsUnknown"
            },
            "then": {
              "properties": {
                "gb": {
                  "type": "null"
                }
              }
            },
            "else": {
              "anyOf": [
                {
                  "required": [
                    "gb"
                  ],
                  "properties": {
                    "gb": {
                      "type": "number"
                    }
                  }
                },
                {
                  "required": [
                    "bytes"
                  ]
                }
              ]
            }
          }
        }
      },
      "UsageHow": {
        "description": "How the fact was obtained: the API call, the page URL, the record, or why it is unknown.",
        "type": "string",
        "minLength": 1
      },
      "UsageIsUnknown": {
        "properties": {
          "source": {
            "const": "unknown"
          }
        },
        "required": [
          "source"
        ]
      },
      "UsageSize": {
        "description": "What the sandbox got. Each field is optional because a source may give only some of them; at least one is present unless the source is `unknown`. When GPUs are present, `gpu` and `gpu_model` are both recorded; without a GPU, both are absent.",
        "type": "object",
        "additionalProperties": false,
        "required": [
          "source",
          "observed_at",
          "how"
        ],
        "properties": {
          "cpu": {
            "description": "vCPUs.",
            "type": "number",
            "exclusiveMinimum": 0
          },
          "memory_mib": {
            "type": "integer",
            "minimum": 1
          },
          "disk_mib": {
            "type": "integer",
            "minimum": 1
          },
          "gpu": {
            "description": "Number of allocated GPUs.",
            "type": "integer",
            "minimum": 1
          },
          "gpu_model": {
            "description": "The allocated model's gpu-registry identifier.",
            "type": "string",
            "pattern": "^[a-z][a-z0-9-]*:[a-z0-9][a-z0-9-]*$"
          },
          "source": {
            "$ref": "#/components/schemas/UsageSource"
          },
          "observed_at": {
            "$ref": "#/components/schemas/PricingTimestamp"
          },
          "how": {
            "$ref": "#/components/schemas/UsageHow"
          }
        },
        "if": {
          "$ref": "#/components/schemas/UsageIsUnknown"
        },
        "then": {
          "not": {
            "anyOf": [
              {
                "required": [
                  "cpu"
                ]
              },
              {
                "required": [
                  "memory_mib"
                ]
              },
              {
                "required": [
                  "disk_mib"
                ]
              },
              {
                "required": [
                  "gpu"
                ]
              },
              {
                "required": [
                  "gpu_model"
                ]
              }
            ]
          }
        },
        "else": {
          "anyOf": [
            {
              "required": [
                "cpu"
              ]
            },
            {
              "required": [
                "memory_mib"
              ]
            },
            {
              "required": [
                "disk_mib"
              ]
            },
            {
              "required": [
                "gpu"
              ]
            }
          ]
        },
        "allOf": [
          {
            "if": {
              "required": [
                "gpu"
              ]
            },
            "then": {
              "required": [
                "gpu_model"
              ]
            }
          },
          {
            "if": {
              "required": [
                "gpu_model"
              ]
            },
            "then": {
              "required": [
                "gpu"
              ]
            }
          }
        ]
      },
      "UsageSnapshotStorage": {
        "description": "The stored snapshot size, or its known maximum when the provider does not report the actual size.",
        "type": "object",
        "additionalProperties": false,
        "required": [
          "source",
          "observed_at",
          "how"
        ],
        "properties": {
          "gb": {
            "type": [
              "number",
              "null"
            ],
            "minimum": 0
          },
          "max_gb": {
            "type": [
              "number",
              "null"
            ],
            "minimum": 0
          },
          "source": {
            "$ref": "#/components/schemas/UsageSource"
          },
          "observed_at": {
            "$ref": "#/components/schemas/PricingTimestamp"
          },
          "how": {
            "$ref": "#/components/schemas/UsageHow"
          },
          "bytes": {
            "description": "Provider snapshot sizeBytes, kept as an exact integer.",
            "type": "integer",
            "minimum": 0
          }
        },
        "if": {
          "$ref": "#/components/schemas/UsageIsUnknown"
        },
        "then": {
          "properties": {
            "gb": {
              "type": "null"
            }
          }
        },
        "else": {
          "anyOf": [
            {
              "required": [
                "gb"
              ],
              "properties": {
                "gb": {
                  "type": "number"
                }
              }
            },
            {
              "required": [
                "bytes"
              ]
            }
          ]
        }
      },
      "UsageRange": {
        "description": "A bounded quantity.",
        "type": "object",
        "additionalProperties": false,
        "required": [
          "low",
          "high"
        ],
        "properties": {
          "low": {
            "type": "number",
            "minimum": 0
          },
          "high": {
            "type": "number",
            "minimum": 0
          }
        }
      },
      "LegacyZeroGpuUsage": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "provider",
          "started",
          "region",
          "size",
          "intervals",
          "creations"
        ],
        "properties": {
          "provider": {
            "$ref": "#/components/schemas/provider"
          },
          "class": {
            "$ref": "#/components/schemas/class"
          },
          "started": {
            "$ref": "#/components/schemas/started"
          },
          "region": {
            "$ref": "#/components/schemas/region"
          },
          "size": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "source",
              "observed_at",
              "how"
            ],
            "properties": {
              "cpu": {
                "$ref": "#/components/schemas/cpu"
              },
              "memory_mib": {
                "$ref": "#/components/schemas/memory_mib"
              },
              "disk_mib": {
                "$ref": "#/components/schemas/disk_mib"
              },
              "gpu": {
                "const": 0
              },
              "gpu_model": {
                "$ref": "#/components/schemas/gpu_model"
              },
              "source": {
                "$ref": "#/components/schemas/UsageSource"
              },
              "observed_at": {
                "$ref": "#/components/schemas/PricingTimestamp"
              },
              "how": {
                "$ref": "#/components/schemas/UsageHow"
              }
            },
            "if": {
              "$ref": "#/components/schemas/UsageIsUnknown"
            },
            "then": {
              "$ref": "#/components/schemas/then"
            },
            "else": {
              "$ref": "#/components/schemas/else"
            },
            "allOf": [
              {
                "if": {
                  "required": [
                    "gpu"
                  ]
                },
                "then": {
                  "required": [
                    "gpu_model"
                  ]
                }
              },
              {
                "if": {
                  "required": [
                    "gpu_model"
                  ]
                },
                "then": {
                  "required": [
                    "gpu"
                  ]
                }
              }
            ]
          },
          "intervals": {
            "$ref": "#/components/schemas/intervals"
          },
          "creations": {
            "$ref": "#/components/schemas/creations"
          },
          "active_cpu": {
            "$ref": "#/components/schemas/active_cpu"
          },
          "egress": {
            "$ref": "#/components/schemas/egress"
          }
        }
      },
      "provider": {
        "description": "The provider that ran the sandbox, as named in its price versions.",
        "type": "string",
        "pattern": "^[a-z][a-z0-9-]*$"
      },
      "class": {
        "description": "The sandbox's class or runtime, which picks the rate set in the price version. If absent, it may be priced only when the price version has exactly one class; otherwise the cost is unknown.",
        "type": "object",
        "additionalProperties": false,
        "required": [
          "name",
          "source",
          "observed_at",
          "how"
        ],
        "properties": {
          "name": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1
          },
          "source": {
            "$ref": "#/components/schemas/UsageSource"
          },
          "observed_at": {
            "$ref": "#/components/schemas/PricingTimestamp"
          },
          "how": {
            "$ref": "#/components/schemas/UsageHow"
          }
        },
        "if": {
          "$ref": "#/components/schemas/UsageIsUnknown"
        },
        "then": {
          "properties": {
            "name": {
              "type": "null"
            }
          }
        },
        "else": {
          "properties": {
            "name": {
              "type": "string"
            }
          }
        }
      },
      "started": {
        "description": "When the sandbox started. It picks the price version in effect.",
        "type": "object",
        "additionalProperties": false,
        "required": [
          "at",
          "source",
          "observed_at",
          "how"
        ],
        "properties": {
          "at": {
            "type": [
              "string",
              "null"
            ]
          },
          "source": {
            "$ref": "#/components/schemas/UsageSource"
          },
          "observed_at": {
            "$ref": "#/components/schemas/PricingTimestamp"
          },
          "how": {
            "$ref": "#/components/schemas/UsageHow"
          }
        },
        "if": {
          "$ref": "#/components/schemas/UsageIsUnknown"
        },
        "then": {
          "properties": {
            "at": {
              "type": "null"
            }
          }
        },
        "else": {
          "properties": {
            "at": {
              "$ref": "#/components/schemas/PricingTimestamp"
            }
          }
        }
      },
      "region": {
        "description": "The region the sandbox ran in, as the provider names it.",
        "type": "object",
        "additionalProperties": false,
        "required": [
          "name",
          "source",
          "observed_at",
          "how"
        ],
        "properties": {
          "name": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1
          },
          "source": {
            "$ref": "#/components/schemas/UsageSource"
          },
          "observed_at": {
            "$ref": "#/components/schemas/PricingTimestamp"
          },
          "how": {
            "$ref": "#/components/schemas/UsageHow"
          }
        },
        "if": {
          "$ref": "#/components/schemas/UsageIsUnknown"
        },
        "then": {
          "properties": {
            "name": {
              "type": "null"
            }
          }
        },
        "else": {
          "properties": {
            "name": {
              "type": "string"
            }
          }
        }
      },
      "cpu": {
        "description": "vCPUs.",
        "type": "number",
        "exclusiveMinimum": 0
      },
      "memory_mib": {
        "type": "integer",
        "minimum": 1
      },
      "disk_mib": {
        "type": "integer",
        "minimum": 1
      },
      "gpu_model": {
        "description": "The allocated model's gpu-registry identifier.",
        "type": "string",
        "pattern": "^[a-z][a-z0-9-]*:[a-z0-9][a-z0-9-]*$"
      },
      "then": {
        "not": {
          "anyOf": [
            {
              "required": [
                "cpu"
              ]
            },
            {
              "required": [
                "memory_mib"
              ]
            },
            {
              "required": [
                "disk_mib"
              ]
            },
            {
              "required": [
                "gpu"
              ]
            },
            {
              "required": [
                "gpu_model"
              ]
            }
          ]
        }
      },
      "else": {
        "anyOf": [
          {
            "required": [
              "cpu"
            ]
          },
          {
            "required": [
              "memory_mib"
            ]
          },
          {
            "required": [
              "disk_mib"
            ]
          },
          {
            "required": [
              "gpu"
            ]
          }
        ]
      },
      "intervals": {
        "description": "Time in each billed state, one entry per period, in time order. A price version's minimum and increment rules apply to each entry.",
        "type": "array",
        "minItems": 1,
        "items": {
          "type": "object",
          "additionalProperties": false,
          "required": [
            "state",
            "seconds",
            "source",
            "observed_at",
            "how"
          ],
          "properties": {
            "size": {
              "$ref": "#/components/schemas/UsageSize"
            },
            "snapshot_storage": {
              "$ref": "#/components/schemas/UsageSnapshotStorage"
            },
            "state": {
              "enum": [
                "running",
                "paused",
                "stopped"
              ]
            },
            "seconds": {
              "description": "Exact seconds, or a range when a change was noticed late and the period is only bounded.",
              "oneOf": [
                {
                  "type": "number",
                  "minimum": 0
                },
                {
                  "$ref": "#/components/schemas/UsageRange"
                },
                {
                  "type": "null"
                }
              ]
            },
            "source": {
              "$ref": "#/components/schemas/UsageSource"
            },
            "observed_at": {
              "$ref": "#/components/schemas/PricingTimestamp"
            },
            "how": {
              "$ref": "#/components/schemas/UsageHow"
            }
          },
          "if": {
            "$ref": "#/components/schemas/UsageIsUnknown"
          },
          "then": {
            "properties": {
              "seconds": {
                "type": "null"
              }
            }
          },
          "else": {
            "properties": {
              "seconds": {
                "type": [
                  "number",
                  "object"
                ]
              }
            }
          }
        }
      },
      "creations": {
        "description": "How many times the sandbox was created: 1, plus any restores that the provider charges as a creation.",
        "type": "object",
        "additionalProperties": false,
        "required": [
          "count",
          "source",
          "observed_at",
          "how"
        ],
        "properties": {
          "count": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0
          },
          "source": {
            "$ref": "#/components/schemas/UsageSource"
          },
          "observed_at": {
            "$ref": "#/components/schemas/PricingTimestamp"
          },
          "how": {
            "$ref": "#/components/schemas/UsageHow"
          }
        },
        "if": {
          "$ref": "#/components/schemas/UsageIsUnknown"
        },
        "then": {
          "properties": {
            "count": {
              "type": "null"
            }
          }
        },
        "else": {
          "properties": {
            "count": {
              "type": "integer"
            }
          }
        }
      },
      "active_cpu": {
        "description": "Seconds of CPU the sandbox actually used, for providers that bill active CPU. Absent where the provider does not bill it.",
        "type": "object",
        "additionalProperties": false,
        "required": [
          "seconds",
          "source",
          "observed_at",
          "how"
        ],
        "properties": {
          "seconds": {
            "type": [
              "number",
              "null"
            ],
            "minimum": 0
          },
          "source": {
            "$ref": "#/components/schemas/UsageSource"
          },
          "observed_at": {
            "$ref": "#/components/schemas/PricingTimestamp"
          },
          "how": {
            "$ref": "#/components/schemas/UsageHow"
          }
        },
        "if": {
          "$ref": "#/components/schemas/UsageIsUnknown"
        },
        "then": {
          "properties": {
            "seconds": {
              "type": "null"
            }
          }
        },
        "else": {
          "properties": {
            "seconds": {
              "type": "number"
            }
          }
        }
      },
      "egress": {
        "description": "Bytes the sandbox sent out. Absent where the provider does not bill it.",
        "type": "object",
        "additionalProperties": false,
        "required": [
          "bytes",
          "source",
          "observed_at",
          "how"
        ],
        "properties": {
          "bytes": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0
          },
          "source": {
            "$ref": "#/components/schemas/UsageSource"
          },
          "observed_at": {
            "$ref": "#/components/schemas/PricingTimestamp"
          },
          "how": {
            "$ref": "#/components/schemas/UsageHow"
          }
        },
        "if": {
          "$ref": "#/components/schemas/UsageIsUnknown"
        },
        "then": {
          "properties": {
            "bytes": {
              "type": "null"
            }
          }
        },
        "else": {
          "properties": {
            "bytes": {
              "type": "integer"
            }
          }
        }
      },
      "SandboxCharge": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "status",
          "reserved_nanodollars",
          "held_nanodollars",
          "lifetime_seconds"
        ],
        "description": "The credit ledger's account of one credit-funded sandbox, in billionths of a US dollar as\nexact decimal strings. `reserved` while it runs: the reservation is held and nothing is\ncharged. `pending` once it has ended and the provider's records are not in: the charge\nis set from them, the reservation stays held, and no amount is reported until they\narrive. `charged` once the records set the charge: `amount_nanodollars` is the current\ncharge and `first_charged_nanodollars` the charge as first settled. A later correction\nmoves the charge by its `delta_nanodollars` and never reopens the reservation.\n",
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "reserved",
              "pending",
              "charged"
            ],
            "x-boxrouter-open-enum": true,
            "description": "Clients must handle unknown values explicitly."
          },
          "reserved_nanodollars": {
            "type": "string",
            "maxLength": 19,
            "pattern": "^(0|[1-9][0-9]{0,18})$",
            "description": "The credit reserved when the sandbox started, for the lifetime it asked for."
          },
          "held_nanodollars": {
            "type": "string",
            "maxLength": 19,
            "pattern": "^(0|[1-9][0-9]{0,18})$",
            "description": "What is still reserved from the balance for this sandbox. Zero once it is charged."
          },
          "lifetime_seconds": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1,
            "description": "The lifetime the reservation was made for. Null when it is not recorded."
          },
          "funding": {
            "type": "string",
            "enum": [
              "fixed",
              "rolling",
              "ending_unfunded"
            ],
            "x-boxrouter-open-enum": true,
            "description": "How the sandbox's credits are reserved. `fixed`: all of the lifetime asked for was\nreserved when the sandbox started. `rolling`: the sandbox was created without a lifetime and\ncredits are reserved one hour at a time, renewed before each hour ends; `funded_until` on\nthe sandbox says how far it is funded. `ending_unfunded`: a renewal could not be\nfunded from the balance, so the sandbox ends at `funded_until`. Clients must handle\nunknown values explicitly. Absent from a Cloud that does not report it yet.\n"
          },
          "first_charged_nanodollars": {
            "type": "string",
            "maxLength": 19,
            "pattern": "^(0|[1-9][0-9]{0,18})$",
            "description": "The charge as first settled from the provider's records. Present only when charged."
          },
          "amount_nanodollars": {
            "type": "string",
            "maxLength": 19,
            "pattern": "^(0|[1-9][0-9]{0,18})$",
            "description": "The charge now: the first charge moved by every correction. Present only when charged;\na pending or reserved charge carries no amount.\n"
          },
          "returned_nanodollars": {
            "type": "string",
            "maxLength": 19,
            "pattern": "^(0|[1-9][0-9]{0,18})$",
            "description": "What went back to the balance when the first charge was settled, the reservation less that charge. Present only when charged."
          },
          "create_fee_nanodollars": {
            "type": "string",
            "maxLength": 19,
            "pattern": "^(0|[1-9][0-9]{0,18})$",
            "description": "The flat per-create fee the price book added to the first charge; zero while no book\nsets one. It is inside `amount_nanodollars`, not on top of it. Present only when\ncharged, and absent from a Cloud that does not report it yet.\n"
          },
          "basis": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "reported",
              "calculated",
              null
            ],
            "x-boxrouter-open-enum": true,
            "description": "How the provider's cost for this sandbox was established, as `cost.label` says for it:\n`reported` for the provider's own figure, `calculated` for one worked out from its\nusage records. Null when the cost's source is not known. Present only when charged.\n"
          },
          "settled_at": {
            "type": "string",
            "format": "date-time",
            "description": "When the first charge was recorded in the ledger. Present only when charged."
          },
          "corrections": {
            "type": "array",
            "maxItems": 1000,
            "description": "Later changes to the charge, oldest first, when the provider's records or reported cost\nfor this sandbox changed after it was first charged. Independent credits an operator\ngives are not corrections. Present only when charged; empty when none.\n",
            "items": {
              "$ref": "#/components/schemas/SandboxChargeCorrection"
            }
          }
        },
        "allOf": [
          {
            "if": {
              "properties": {
                "status": {
                  "const": "charged"
                }
              },
              "required": [
                "status"
              ]
            },
            "then": {
              "required": [
                "first_charged_nanodollars",
                "amount_nanodollars",
                "returned_nanodollars",
                "settled_at",
                "corrections"
              ]
            },
            "else": {
              "properties": {
                "first_charged_nanodollars": false,
                "amount_nanodollars": false,
                "returned_nanodollars": false,
                "create_fee_nanodollars": false,
                "basis": false,
                "settled_at": false,
                "corrections": false
              }
            }
          }
        ]
      },
      "SandboxChargeCorrection": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "at",
          "delta_nanodollars",
          "reason"
        ],
        "properties": {
          "at": {
            "type": "string",
            "format": "date-time",
            "description": "When the ledger recorded the correction."
          },
          "delta_nanodollars": {
            "type": "string",
            "maxLength": 20,
            "pattern": "^(-?[1-9][0-9]{0,18})$",
            "description": "The change to the charge. Positive means the charge went up and the difference was taken from the balance; negative means it went down and the difference was returned to it."
          },
          "reason": {
            "type": "string",
            "enum": [
              "provider_revised"
            ],
            "x-boxrouter-open-enum": true,
            "description": "Why the charge moved. `provider_revised`: the provider's records or reported cost for\nthis sandbox changed. Clients must handle unknown values explicitly.\n"
          }
        }
      },
      "SandboxRoute": {
        "type": "object",
        "required": [
          "provider",
          "class",
          "adapter_version",
          "selection"
        ],
        "description": "The adapter that made this sandbox. Support questions start at adapter_version. A sandbox\nwith no recorded contract still names its provider and account; its class and\nadapter_version are null.\n",
        "properties": {
          "id": {
            "type": [
              "string",
              "null"
            ]
          },
          "provider": {
            "type": "string"
          },
          "class": {
            "type": [
              "string",
              "null"
            ],
            "description": "The declaration's class, such as a provider's VM class; null when the adapter publishes one declaration."
          },
          "adapter_version": {
            "type": [
              "string",
              "null"
            ]
          },
          "account_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "supply": {
            "type": [
              "string",
              "null"
            ]
          },
          "region": {
            "type": [
              "string",
              "null"
            ]
          },
          "native_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Provider-owned sandbox identifier; null when unavailable."
          },
          "selection": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/SandboxRouteSelection"
              },
              {
                "type": "null"
              }
            ],
            "description": "Null in listings, which look at no route."
          }
        }
      },
      "SandboxRouteSelection": {
        "type": "object",
        "required": [
          "considered",
          "eligible",
          "ranked_by",
          "excluded",
          "attempts"
        ],
        "description": "Which routes were considered, how they were ranked and why each other one was excluded.",
        "properties": {
          "considered": {
            "type": "integer",
            "minimum": 0
          },
          "eligible": {
            "type": "integer",
            "minimum": 0
          },
          "ranked_by": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "price",
              "time",
              "providers",
              "order",
              null
            ],
            "x-boxrouter-choices": {
              "price": {
                "label": "Price",
                "line": "Lowest hourly price first.",
                "measure": "price",
                "better": "lower"
              },
              "time": {
                "label": "Time",
                "line": "Shortest run time measured on reference workloads first.",
                "measure": "time",
                "better": "lower"
              },
              "providers": {
                "label": "Providers",
                "line": "The hard list order."
              },
              "order": {
                "label": "Order",
                "line": "A soft provider preference."
              }
            },
            "description": "The sort used; providers for the hard list order; order for a soft provider preference; or null for the router's default."
          },
          "excluded": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ExcludedRoute"
            }
          },
          "preparation_skips": {
            "type": "array",
            "description": "Routes skipped after eligibility because image or provider preparation failed.",
            "items": {
              "$ref": "#/components/schemas/CreationPreparationSkip"
            }
          },
          "attempts": {
            "type": "array",
            "description": "Adapters that refused this create before the one that made it, in dispatch order. Only\ndispatches appear; routes skipped before dispatch are in `excluded`. Normally empty:\nBoxRouter tries the next eligible adapter once when a refusal is definite.\n",
            "items": {
              "type": "object",
              "required": [
                "provider",
                "native_code",
                "native_status"
              ],
              "properties": {
                "provider": {
                  "type": "string"
                },
                "native_code": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "native_status": {
                  "type": [
                    "integer",
                    "null"
                  ]
                },
                "route_id": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "maxLength": 128,
                  "description": "The route this dispatch used."
                },
                "account_id": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "maxLength": 128,
                  "description": "The connected account this dispatch used."
                },
                "supply": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "maxLength": 32,
                  "description": "The funding authority of this dispatch: byok or managed."
                },
                "cause": {
                  "$ref": "#/components/schemas/CreationRouteCause"
                }
              }
            }
          },
          "fallbacks_allowed": {
            "type": "boolean",
            "description": "The effective allow_fallbacks after inheritance. Absent when the create predates this field."
          },
          "stopped_reason": {
            "$ref": "#/components/schemas/CreationStoppedReason"
          },
          "funding_group": {
            "$ref": "#/components/schemas/FundingGroup",
            "description": "Frozen payer group of the selected route. Absent on older responses; definite pre-create fallback stays in this group after dispatch."
          },
          "workspace_mode": {
            "type": "string",
            "enum": [
              "automatic",
              "cheapest",
              "fastest",
              "custom"
            ],
            "x-boxrouter-open-enum": true,
            "x-boxrouter-choices": {
              "automatic": {
                "label": "Auto",
                "line": "A random draw weighted toward lower hourly price."
              },
              "cheapest": {
                "label": "Cheapest",
                "line": "Lowest hourly price first.",
                "measure": "price",
                "better": "lower"
              },
              "fastest": {
                "label": "Fastest",
                "line": "Shortest run time measured on reference workloads first.",
                "measure": "time",
                "better": "lower"
              },
              "custom": {
                "label": "Custom",
                "line": "Your exact provider order, top to bottom."
              }
            },
            "description": "Effective workspace mode at admission; absent on older responses."
          }
        }
      },
      "ExcludedRoute": {
        "type": "object",
        "required": [
          "provider",
          "class",
          "account_id",
          "failed"
        ],
        "description": "One candidate that was not eligible, with every check it failed.",
        "properties": {
          "provider": {
            "type": "string"
          },
          "class": {
            "type": [
              "string",
              "null"
            ]
          },
          "account_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "failed": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FailedCheck"
            }
          }
        }
      },
      "FailedCheck": {
        "type": "object",
        "required": [
          "reason"
        ],
        "description": "One failed check, in the order they are made: baseline, then the gates in the spec's\norder with extras last, then conflicts, resources and basis.\n",
        "properties": {
          "reason": {
            "type": "string",
            "description": "gate_not_listed, gate_unsupported, gate_unavailable, knob_mismatch, knob_unknown,\nconflict, resource_mismatch, resource_unknown, not_proven, limit_exceeded,\nbound_elsewhere, extra_mismatch, declaration_unusable, variant_unusable,\nbaseline_failed, account_unchecked, account_unhealthy, standard_image_unavailable,\nnot_allowed, `not connected`, `not enabled`, price_unknown, insufficient_credit,\nspend_limit_exceeded, outside_funding_authority, unfunded or class_not_selected.\n`standard_image_unavailable` means the account has no verified copy of the standard image\nfor the route's exact region, image version and digest; its `fix` field gives the setup fix.\nIt is distinct from `baseline_failed`, which means the provider cannot meet the requested\ncontract. `price_unknown` means the payer's price is unknown; `insufficient_credit` means\nthe payer has fewer credits than required; `spend_limit_exceeded` means the applicable\nspend limit prevents the request. These typed funding refusals apply only when a payer\nexists. `unfunded` means no provider key and no credits, not merely zero available credits.\n`outside_funding_authority` means the matched route is outside the funding ceiling selected\nfor this request. `not connected` means the provider is served by this deployment but no\naccount is connected to this workspace; `not enabled` means the provider is not served by\nthis deployment. `class_not_selected` means a matched sibling class lost the\none-class-per-route selection while its route remains inside the authority ceiling; it\nexcludes the class, not the route. `open_ended_unfit` means the provider can end a\nsandbox, so it cannot serve one with `lifetime_seconds: null`; `open_ended_needs_byok`\nmeans that request was made on a credit-funded route. Clients must tolerate reasons\nthey do not know.\n"
          },
          "gate": {
            "type": "string"
          },
          "knob": {
            "type": "string"
          },
          "resource": {
            "type": "string"
          },
          "extra": {
            "type": "string"
          },
          "limit": {
            "type": "string"
          },
          "detail": {
            "type": [
              "string",
              "null"
            ]
          },
          "details": {
            "type": "object",
            "description": "Structured facts for the refusal, such as available and required credits or the applicable\nspend limit.\n",
            "additionalProperties": true
          },
          "fix": {
            "type": [
              "string",
              "null"
            ],
            "description": "Setup action for this failed check, when one is available."
          },
          "asked": {
            "description": "What the request asked for, in the request's own form."
          },
          "offered": {
            "description": "What the declaration offers, in the declaration's own form."
          },
          "narrowed_by": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "account",
              null
            ]
          },
          "between": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "value": {
            "description": "The one value that caused the failure, when one did."
          }
        }
      },
      "Contract": {
        "type": "object",
        "required": [
          "spec_version",
          "gates",
          "resources",
          "attested"
        ],
        "description": "What this sandbox may use, fixed at creation. No gate is ever added to a running sandbox.",
        "properties": {
          "spec_version": {
            "type": "string",
            "pattern": "^(boxspec|sandbox-provider-spec)/[0-9]+\\.[0-9]+(-draft(\\.[0-9]+)?)?$"
          },
          "gates": {
            "type": "object",
            "additionalProperties": {
              "$ref": "#/components/schemas/GrantedGate"
            }
          },
          "resources": {
            "type": "object",
            "additionalProperties": true,
            "description": "What was provisioned, plus the adapter's answers for long_running and extendable_lifetime. A value may be \"unknown\" or null."
          },
          "attested": {
            "type": "object",
            "description": "Which resource values rest on a dated citation rather than on adapter code.",
            "additionalProperties": {
              "type": "object",
              "required": [
                "source",
                "read"
              ],
              "properties": {
                "source": {
                  "type": "string"
                },
                "read": {
                  "type": "string",
                  "format": "date"
                }
              }
            }
          }
        }
      },
      "GrantedGate": {
        "type": "object",
        "required": [
          "variant",
          "basis",
          "granted",
          "also",
          "settings",
          "unavailable"
        ],
        "description": "One gate as granted to this sandbox.",
        "properties": {
          "variant": {
            "type": "integer",
            "minimum": 0,
            "description": "Index into the declaration of route.adapter_version. Only meaningful with that version."
          },
          "basis": {
            "type": "string",
            "enum": [
              "implemented",
              "proven"
            ],
            "description": "The weakest basis among the granted values; for a gate granted with no named knob, the variant's own."
          },
          "granted": {
            "type": "object",
            "additionalProperties": true,
            "description": "One entry per knob the request named: the granted values for a pick-one knob, the\nstring \"any\" where the request said so, the boolean for a yes/no knob, the declared\nnumber for a number knob. This is what the code may rely on.\n"
          },
          "also": {
            "type": "object",
            "additionalProperties": true,
            "description": "The variant's other answers, including declared limits, for information. Calls that depend on them are refused."
          },
          "settings": {
            "type": "object",
            "additionalProperties": true
          },
          "unavailable": {
            "type": [
              "string",
              "null"
            ],
            "description": "Set when the account has since lost the gate; that gate's calls then answer gate_unavailable."
          }
        }
      },
      "SandboxRequestSnapshot": {
        "type": "object",
        "additionalProperties": true,
        "description": "The recorded creation request after server-side expansion and defaulting, without\nrequest-only secret values, environment values or labels. A sandbox can outlive the\ncreate-request schema that was current when it was made, so this historical snapshot\naccepts fields from earlier contract versions. Clients should interpret only fields\nthey recognize and preserve unknown fields when displaying or storing the snapshot.\n"
      },
      "HiddenSecretResult": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "placeholder",
          "hosts"
        ],
        "properties": {
          "placeholder": {
            "type": "string",
            "minLength": 1,
            "description": "The safe token to place where this secret should be used."
          },
          "hosts": {
            "type": "array",
            "uniqueItems": true,
            "items": {
              "allOf": [
                {
                  "$ref": "#/components/schemas/SandboxProviderSpecHostname"
                },
                {
                  "type": "string"
                }
              ]
            },
            "description": "Hosts to which the adapter sends this secret."
          }
        }
      },
      "TcpPortEndpoint": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "host",
          "port",
          "tls"
        ],
        "properties": {
          "host": {
            "type": "string",
            "minLength": 1
          },
          "port": {
            "type": "integer",
            "minimum": 1,
            "maximum": 65535
          },
          "tls": {
            "type": "string",
            "enum": [
              "none",
              "terminated"
            ]
          }
        }
      },
      "SandboxLimits": {
        "type": "object",
        "properties": {
          "buffered_output_bytes": {
            "type": "integer",
            "minimum": 1,
            "description": "Maximum combined stdout/stderr for the buffered command endpoint."
          },
          "file_transfer_bytes": {
            "type": "integer",
            "minimum": 1,
            "default": 1048576,
            "description": "Maximum file size of `readFile` and `writeFile` on this route."
          },
          "upload_max_bytes": {
            "type": "integer",
            "minimum": 0,
            "description": "Per route, the largest file `createSandboxUpload` accepts."
          },
          "download_max_bytes": {
            "type": "integer",
            "minimum": 0,
            "description": "Per route, the largest file `createSandboxDownload` accepts."
          },
          "inline_transfer_max_bytes": {
            "type": "integer",
            "minimum": 1,
            "description": "Largest file this route serves inline in one createSandboxDownload (send\n`inline_below`) or relays for upload, cheaper than its transfer link;\nabsent when the route has none.\n"
          }
        }
      },
      "VolumeAttachment": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "path",
          "access",
          "restored_checkpoint",
          "restore_duration_ms"
        ],
        "properties": {
          "id": {
            "$ref": "#/components/schemas/VolumeId"
          },
          "path": {
            "type": "string"
          },
          "access": {
            "type": "string",
            "enum": [
              "write",
              "read",
              "shared",
              "branch"
            ]
          },
          "restored_checkpoint": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1
          },
          "restore_duration_ms": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0
          }
        }
      },
      "SandboxPage": {
        "type": "object",
        "required": [
          "data",
          "next_cursor",
          "counts"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Sandbox"
            }
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ]
          },
          "counts": {
            "$ref": "#/components/schemas/SandboxListCounts"
          }
        }
      },
      "SandboxListCounts": {
        "type": "object",
        "required": [
          "live",
          "ended",
          "by_state"
        ],
        "description": "Counts across all pages matching the other query filters. live and ended ignore\nlifecycle; by_state also ignores the state filter. Values are workspace scoped.\n",
        "properties": {
          "live": {
            "type": "integer",
            "minimum": 0
          },
          "ended": {
            "type": "integer",
            "minimum": 0
          },
          "by_state": {
            "type": "object",
            "additionalProperties": {
              "type": "integer",
              "minimum": 0
            }
          }
        }
      },
      "MatchResult": {
        "type": "object",
        "required": [
          "spec_version",
          "request",
          "eligible",
          "excluded",
          "nearest",
          "closest"
        ],
        "description": "What creating with the same body would do, without provisioning, reserving or\nrecording anything. An empty eligible list is a 200 for ordinary capability exclusions.\nWith a payer, typed funding refusals appear as exclusions when another funding candidate\nremains eligible; if every funding candidate is refused, the request returns the selected\ntyped refusal as an error. A workspace with no provider key and no credits gets a 409\nno_eligible_route naming both remedies; a workspace with no candidate at all also gets a 409\nno_eligible_route. Matched classes omitted by the one-class-per-route selection appear in\nexcluded.\n",
        "properties": {
          "spec_version": {
            "type": "string",
            "pattern": "^(boxspec|sandbox-provider-spec)/[0-9]+\\.[0-9]+(-draft(\\.[0-9]+)?)?$"
          },
          "request": {
            "allOf": [
              {
                "$ref": "#/components/schemas/CreateSandbox"
              }
            ],
            "description": "The body as matched, with profiles expanded and defaults filled in."
          },
          "eligible": {
            "type": "array",
            "description": "The eligible candidates, in the order creation would try them.",
            "items": {
              "$ref": "#/components/schemas/EligibleRoute"
            }
          },
          "excluded": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ExcludedRoute"
            }
          },
          "nearest": {
            "type": "array",
            "description": "The smallest changes that would make a route eligible, fewest changes first, then\nmost routes gained. A change maps a dotted path in the request to its new value,\nnull meaning remove it.\n",
            "items": {
              "type": "object",
              "required": [
                "change",
                "then_eligible"
              ],
              "properties": {
                "change": {
                  "type": "object",
                  "additionalProperties": true
                },
                "then_eligible": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              }
            }
          },
          "closest": {
            "description": "The excluded candidate that failed the fewest checks, or null when none was excluded.",
            "oneOf": [
              {
                "$ref": "#/components/schemas/ExcludedRoute"
              },
              {
                "type": "null"
              }
            ]
          }
        }
      },
      "EligibleRoute": {
        "type": "object",
        "required": [
          "provider",
          "class",
          "account_id",
          "supply",
          "adapter_version",
          "gates",
          "resources",
          "attested",
          "lifetime"
        ],
        "description": "One candidate that fits, with the contract it would grant.",
        "properties": {
          "provider": {
            "type": "string"
          },
          "class": {
            "type": [
              "string",
              "null"
            ]
          },
          "account_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "supply": {
            "type": "string"
          },
          "adapter_version": {
            "type": "string"
          },
          "gates": {
            "type": "object",
            "additionalProperties": {
              "$ref": "#/components/schemas/GrantedGate"
            }
          },
          "resources": {
            "type": "object",
            "additionalProperties": true
          },
          "attested": {
            "type": "object",
            "additionalProperties": true
          },
          "lifetime": {
            "$ref": "#/components/schemas/Lifetime"
          },
          "ranking": {
            "$ref": "#/components/schemas/EligibleRouteRanking"
          },
          "request_overrides": {
            "type": "object",
            "additionalProperties": false,
            "minProperties": 1,
            "description": "The create request fields a caller must send to make this route eligible and priceable.\nCopy these fields into the create request and keep the caller's other fields. The object\nmay select this route's funding authority, choose an image or lifetime, or name resources\nused to quote a managed route. Fields are never merged across routes.\n",
            "properties": {
              "route": {
                "$ref": "#/components/schemas/CreationRouteFilter",
                "description": "The funding authority that this route requires."
              },
              "image": {
                "type": "string",
                "const": "provider_default",
                "description": "Use the image selected by this route's provider."
              },
              "lifetime_seconds": {
                "$ref": "#/components/schemas/lifetime_seconds",
                "description": "The lifetime the create request must send for this route."
              },
              "resources": {
                "$ref": "#/components/schemas/SandboxProviderSpecResources",
                "description": "The resource ask used to establish this route's eligibility and price."
              }
            }
          }
        }
      },
      "EligibleRouteRanking": {
        "type": "object",
        "required": [
          "position",
          "reason",
          "explanation",
          "price"
        ],
        "description": "Why this route sits where it does in the order creation would try, with its hourly quote.\nIt explains the ordering of this dry run; creation re-ranks with the signals of that moment.\nAbsent on responses from a Cloud that predates it.\n",
        "properties": {
          "position": {
            "type": "integer",
            "minimum": 1,
            "description": "Place in the order creation would try, 1 first."
          },
          "reason": {
            "type": "string",
            "enum": [
              "lowest_price",
              "weighted_price",
              "lowest_time",
              "time_unmeasured",
              "predicted_completion",
              "predicted_ready_time",
              "explicit_order",
              "after_named_providers",
              "provider_key_order",
              "only_eligible_route",
              "health_deprioritized",
              "price_unknown",
              "no_signals"
            ],
            "x-boxrouter-open-enum": true,
            "x-boxrouter-choices": {
              "lowest_price": {
                "label": "Lowest price",
                "line": "Lowest hourly price of the routes ranked together."
              },
              "weighted_price": {
                "label": "Weighted price",
                "line": "Automatic mode leads with a draw weighted toward lower prices, so the leader can change between creates; the routes behind it follow by price."
              },
              "lowest_time": {
                "label": "Lowest time",
                "line": "Shortest run time measured on reference workloads first."
              },
              "time_unmeasured": {
                "label": "Time unmeasured",
                "line": "No current run time was measured for this provider on reference workloads, so it follows the measured routes, ordered by ready time, then price."
              },
              "predicted_completion": {
                "label": "Predicted completion",
                "line": "Soonest predicted completion among the routes ranked together."
              },
              "predicted_ready_time": {
                "label": "Predicted ready time",
                "line": "Ordered by predicted time to ready from this workspace's history."
              },
              "explicit_order": {
                "label": "Explicit order",
                "line": "Placed by the provider order you set in Routing or in the request."
              },
              "after_named_providers": {
                "label": "After named providers",
                "line": "Behind the providers you named in your order; the others keep BoxRouter's ranking."
              },
              "provider_key_order": {
                "label": "Provider key order",
                "line": "Another key of a provider already placed; one provider's keys are tried in the order you set in Routing."
              },
              "only_eligible_route": {
                "label": "Only eligible route",
                "line": "Nothing else to rank it against in its group."
              },
              "health_deprioritized": {
                "label": "Health deprioritized",
                "line": "Recent failures or degraded health put it behind healthier routes."
              },
              "price_unknown": {
                "label": "Price unknown",
                "line": "No price quote at this size, so routes with a quote are tried first."
              },
              "no_signals": {
                "label": "No signals",
                "line": "No price or time signals exist yet, so it keeps BoxRouter's default order."
              }
            },
            "description": "Why the route ranks here. explicit_order is your own provider order; after_named_providers is a provider behind the ones you named; provider_key_order is\na later key of a provider already placed; time_unmeasured means a time sort has no current\nmeasured run time for the route's provider; price_unknown means no comparable hourly quote\nis available. New values may appear.\n"
          },
          "explanation": {
            "type": "string",
            "description": "The reason in one sentence; any price mention refers to the hourly quote in price."
          },
          "price": {
            "type": "object",
            "required": [
              "usd_per_hour",
              "kind",
              "basis"
            ],
            "description": "The hourly quote at the size this route would grant. For BYOK, kind `list_price` is the provider list price paid directly to the provider; for managed supply, kind `customer_price` is BoxRouter's customer price charged to credits. This is not a final bill or a complete-task estimate.",
            "properties": {
              "usd_per_hour": {
                "type": [
                  "string",
                  "null"
                ],
                "pattern": "^(0|[1-9][0-9]*)(\\.[0-9]+)?$",
                "description": "Null when the size is unknown or the price version has no quote for it."
              },
              "kind": {
                "type": "string",
                "enum": [
                  "list_price",
                  "customer_price",
                  "unknown"
                ],
                "x-boxrouter-open-enum": true,
                "description": "Kind of hourly quote; unknown means no quote is available."
              },
              "basis": {
                "type": "string",
                "description": "The size priced and whose price it is, or why there is no price."
              }
            }
          }
        }
      },
      "lifetime_seconds": {
        "type": [
          "integer",
          "null"
        ],
        "minimum": 60,
        "description": "The sandbox's lifetime in seconds, starting when BoxRouter begins creation on the\nselected route. Creation time counts, so less time may remain when the sandbox is\nready. The minimum is 60 seconds. The requested value is matched against the route's\nmax_lifetime_seconds, and a credit-funded sandbox reserves credits for all of it.\n\nLeave it out for a credit-funded sandbox on a route that can extend a lifetime\n(`extendable_lifetime`) and the sandbox runs for as long as the workspace's credit\nbalance covers it: credits are reserved one hour at a time and renewed before each\nhour ends. `funded_until` on the sandbox says when the current reservation ends; the\nsandbox ends then if the balance could not cover another hour. Left out on any other\ncreate (a route that cannot extend a lifetime, or a sandbox paid with the workspace's\nown provider account), it is 300 seconds.\n\nNull asks for a sandbox with no lifetime: it runs until you destroy it. Only a provider\nthat never ends a sandbox serves it, and only on the workspace's own provider account;\nleave at_end out with it.\n"
      },
      "RunCommand": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "command"
        ],
        "description": "The one command request body. output chooses how the output comes back; a body that\nleaves it out asks for text. output_limit_bytes bounds each stream in either form.\n",
        "properties": {
          "command": {
            "x-boxrouter-input-error": "Command must not contain NUL bytes",
            "type": "string",
            "pattern": "^[^\\u0000]*$",
            "description": "Bash source executed once, including an empty script. NUL characters are invalid. Must not appear in operational logs by default."
          },
          "env": {
            "x-boxrouter-input-error": "Command env requires valid shell variable names and values without NUL",
            "type": [
              "object",
              "null"
            ],
            "propertyNames": {
              "pattern": "^[A-Za-z_][A-Za-z0-9_]*(?![\\s\\S])"
            },
            "additionalProperties": {
              "type": "string",
              "pattern": "^[^\\u0000]*$"
            },
            "description": "Literal environment overrides for this command only, applied after shell initialization. Omission or null retains the provider environment. Not logged."
          },
          "cwd": {
            "x-boxrouter-input-error": "Command cwd must be an absolute sandbox path without NUL bytes",
            "type": [
              "string",
              "null"
            ],
            "pattern": "^/[^\\u0000]*$",
            "description": "Absolute sandbox working directory for this command only. Omitted, the command runs\nin the sandbox's default directory.\n"
          },
          "timeout_seconds": {
            "x-boxrouter-input-error": "Command timeout_seconds must be a positive integer",
            "type": "integer",
            "minimum": 1,
            "default": 60,
            "description": "Execution limit in seconds. At the deadline the command's process group receives TERM,\nthen KILL 5 seconds later; children that leave the process group are not ended. The\ncall may return shortly after the deadline while it finishes collecting output, and\nanswers 200 with timed_out true, exit_code null and the output written until then.\n"
          },
          "output": {
            "type": "string",
            "enum": [
              "text",
              "bytes"
            ],
            "default": "text",
            "description": "How the result carries what the command wrote. text: stdout and stderr as strings,\nwith invalid bytes replaced. bytes: stdout_base64 and stderr_base64 instead, the\nexact bytes, so a caller reads one pair or the other and never both (D26).\n"
          },
          "output_limit_bytes": {
            "$ref": "#/components/schemas/OutputLimitBytes"
          }
        }
      },
      "OutputLimitBytes": {
        "type": "integer",
        "minimum": 1,
        "maximum": 524288,
        "default": 524288,
        "description": "The most bytes returned from each of stdout and stderr: 512 KiB by default and at most,\nhalf the advertised limits.buffered_output_bytes (1 MiB) that both streams share. Output\nover the limit does not fail the command: the result carries the exit status and the first\noutput_limit_bytes of that stream, with its truncated flag true. A value above the maximum\nis a validation error before any dispatch. Use a process for complete large output.\n"
      },
      "CommandResult": {
        "type": "object",
        "required": [
          "stdout",
          "stderr",
          "exit_code",
          "timed_out",
          "stdout_truncated",
          "stderr_truncated"
        ],
        "description": "What a command answers. A nonzero exit_code and a timeout are both a 200 with a result,\nnever an HTTP failure; a client that wants an error raises it from the result (check).\n",
        "properties": {
          "stdout": {
            "type": "string"
          },
          "stderr": {
            "type": "string"
          },
          "exit_code": {
            "$ref": "#/components/schemas/ExitCode"
          },
          "timed_out": {
            "$ref": "#/components/schemas/TimedOut"
          },
          "stdout_truncated": {
            "$ref": "#/components/schemas/OutputTruncated"
          },
          "stderr_truncated": {
            "$ref": "#/components/schemas/OutputTruncated"
          },
          "native_error": {
            "type": [
              "string",
              "null"
            ],
            "description": "Provider-reported error for this command, unchanged, when the provider supplies\none; otherwise null. It supplements exit_code without changing its meaning.\n"
          }
        }
      },
      "ExitCode": {
        "type": [
          "integer",
          "null"
        ],
        "description": "The command's exit status. Null only when timed_out is true: a command that was ended at its\ndeadline did not exit on its own, so it has no status.\n"
      },
      "TimedOut": {
        "type": "boolean",
        "description": "True when the command reached its timeout_seconds and BoxRouter ended its process group.\nThe result then carries the output the command wrote before that point, and exit_code is\nnull. False for every command that exited on its own, whatever its exit_code.\n"
      },
      "OutputTruncated": {
        "type": "boolean",
        "description": "True when the stream wrote more than output_limit_bytes and only the first output_limit_bytes are returned."
      },
      "ByteCommandResult": {
        "type": "object",
        "required": [
          "stdout_base64",
          "stderr_base64",
          "exit_code",
          "timed_out",
          "stdout_truncated",
          "stderr_truncated",
          "native_error"
        ],
        "description": "What a command asked for bytes answers: the exact bytes it wrote, base64, in place of\nthe strings. A nonzero exit_code and a timeout are still a 200.\n",
        "properties": {
          "stdout_base64": {
            "type": "string",
            "contentEncoding": "base64"
          },
          "stderr_base64": {
            "type": "string",
            "contentEncoding": "base64"
          },
          "exit_code": {
            "$ref": "#/components/schemas/ExitCode"
          },
          "timed_out": {
            "$ref": "#/components/schemas/TimedOut"
          },
          "stdout_truncated": {
            "$ref": "#/components/schemas/OutputTruncated"
          },
          "stderr_truncated": {
            "$ref": "#/components/schemas/OutputTruncated"
          },
          "native_error": {
            "type": [
              "string",
              "null"
            ],
            "description": "Always null in this form: a provider reports one against the text result, which is\nthe only one that has it. Present so no field of a result is ever absent.\n"
          }
        }
      },
      "CreateSandboxUpload": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "path",
          "size"
        ],
        "properties": {
          "path": {
            "type": "string",
            "minLength": 1,
            "pattern": "^/[^\\u0000]*$",
            "description": "Absolute path inside the sandbox, validated like `writeFile`."
          },
          "size": {
            "type": "integer",
            "minimum": 0,
            "description": "Exact file size in bytes. At most the route's `limits.upload_max_bytes`, otherwise `resource_limit` (413)."
          }
        }
      },
      "SandboxUpload": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "sandbox_id",
          "path",
          "size",
          "route",
          "part_size",
          "parts",
          "expires_at"
        ],
        "description": "Upload session. Send every part as its `TransferPart` describes, then complete with each\nresponse `ETag`, if any. Part URLs may embed secret signatures: never log them. The links\nand this session last up to six hours after creation and end at `expires_at`. At launch\nthere is exactly one part.\n",
        "properties": {
          "id": {
            "$ref": "#/components/schemas/SandboxUploadId"
          },
          "sandbox_id": {
            "type": "string",
            "minLength": 1
          },
          "path": {
            "type": "string",
            "minLength": 1,
            "pattern": "^/[^\\u0000]*$"
          },
          "size": {
            "type": "integer",
            "minimum": 0
          },
          "route": {
            "$ref": "#/components/schemas/SandboxTransferRoute"
          },
          "part_size": {
            "type": "integer",
            "minimum": 0,
            "description": "Bytes per part except the last. Equals `size` for a single part, or 0 for an empty file."
          },
          "parts": {
            "type": "array",
            "minItems": 1,
            "maxItems": 10000,
            "items": {
              "$ref": "#/components/schemas/TransferPart"
            }
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "description": "When the part links and this session end; at most six hours after creation."
          }
        }
      },
      "SandboxUploadId": {
        "type": "string",
        "pattern": "^sup_[0-9a-f]{32}$"
      },
      "SandboxTransferRoute": {
        "type": "string",
        "enum": [
          "direct",
          "relay"
        ],
        "x-boxrouter-open-enum": true,
        "description": "Informational. Which path the bytes take. Clients must not branch on it."
      },
      "TransferPart": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "number",
          "size",
          "url"
        ],
        "description": "One request a client makes to move part of a file. Volume upload parts are this shape with\nevery default, so one client serves both. The response `ETag` header, if any, is\npassed back on completion; an absent `ETag` is passed as no `etag`.\n",
        "properties": {
          "number": {
            "type": "integer",
            "minimum": 1,
            "maximum": 10000
          },
          "size": {
            "type": "integer",
            "minimum": 0,
            "description": "Exact byte count of this part."
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "Where to send this part. The URL may embed a secret signature: clients must never log\nit, include it in error messages, or persist it. Treat it as opaque.\n"
          },
          "method": {
            "type": "string",
            "enum": [
              "PUT",
              "POST"
            ],
            "default": "PUT",
            "description": "HTTP method to use."
          },
          "headers": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "default": {},
            "description": "Headers the client must send with this request, exactly as given."
          },
          "form_field": {
            "type": "string",
            "minLength": 1,
            "description": "When present, send the bytes as `multipart/form-data` with a single file field of this\nname. When absent, send the raw bytes as the request body with `Content-Length` equal to\n`size`.\n"
          }
        }
      },
      "CompleteSandboxUpload": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "parts"
        ],
        "properties": {
          "parts": {
            "type": "array",
            "minItems": 1,
            "maxItems": 10000,
            "description": "Each part number exactly once.",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "number"
              ],
              "properties": {
                "number": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 10000
                },
                "etag": {
                  "type": "string",
                  "minLength": 1,
                  "description": "The response `ETag` header for this part. Omit when the response had none."
                }
              }
            }
          }
        }
      },
      "CompletedSandboxUpload": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "path",
          "size"
        ],
        "properties": {
          "path": {
            "type": "string",
            "minLength": 1,
            "pattern": "^/[^\\u0000]*$"
          },
          "size": {
            "type": "integer",
            "minimum": 0
          }
        }
      },
      "CreateSandboxDownload": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "path"
        ],
        "properties": {
          "path": {
            "type": "string",
            "minLength": 1,
            "pattern": "^/[^\\u0000]*$",
            "description": "Absolute path of an existing file inside the sandbox."
          },
          "inline_below": {
            "type": "integer",
            "minimum": 0,
            "description": "Optional byte floor, chosen by the caller: when the provider reports the file's size below this value the response's `content` carries the body inline instead of creating a link. At or above it a link is created as usual — a provider-direct one where the route supports it."
          }
        }
      },
      "SandboxDownload": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "path",
          "size"
        ],
        "description": "Download answer: when `content` is present it carries the file body inline (base64) and no link exists; otherwise `url` and `expires_at` give a temporary link that lasts up to one hour after creation. The URL may embed a secret signature, so never log it.",
        "properties": {
          "path": {
            "type": "string",
            "minLength": 1,
            "pattern": "^/[^\\u0000]*$"
          },
          "size": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0,
            "description": "File size in bytes when the provider reports it; null when it is not known until the download's response. A complete download ends exactly at its response's Content-Length."
          },
          "content": {
            "type": "string",
            "description": "The file body, base64-encoded, when `inline_below` admitted it. Absent when a link was created instead."
          },
          "route": {
            "$ref": "#/components/schemas/SandboxTransferRoute"
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "Temporary download link; absent when `content` carries the body."
          },
          "method": {
            "type": "string",
            "enum": [
              "GET"
            ],
            "default": "GET"
          },
          "headers": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "default": {}
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "description": "When the link ends; at most one hour after creation. Absent when `content` carries the body."
          }
        }
      },
      "DirectoryEntry": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "name",
          "type"
        ],
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "description": "The entry's name within the directory, without a path."
          },
          "type": {
            "type": "string",
            "enum": [
              "file",
              "directory",
              "symlink",
              "other"
            ],
            "description": "What the entry itself is. A symbolic link is symlink whether or not its target exists; it is never followed."
          }
        }
      },
      "CreateDirectoryRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "path"
        ],
        "properties": {
          "path": {
            "type": "string",
            "minLength": 1,
            "pattern": "^/[^\\u0000]*$"
          },
          "parents": {
            "type": "boolean",
            "default": true
          }
        }
      },
      "RemovePathRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "path"
        ],
        "properties": {
          "path": {
            "type": "string",
            "minLength": 1,
            "pattern": "^/[^\\u0000]*$"
          },
          "recursive": {
            "type": "boolean",
            "default": false
          }
        }
      },
      "PriceVersionPage": {
        "type": "object",
        "required": [
          "data"
        ],
        "properties": {
          "data": {
            "type": "array",
            "description": "Live price versions, newest `effective_from` first. Not paginated: there are a few\nversions per provider. Empty when nothing matches, including an unknown `provider`.\n",
            "items": {
              "$ref": "#/components/schemas/PriceVersion"
            }
          }
        }
      },
      "PriceVersion": {
        "type": "object",
        "required": [
          "provider",
          "version",
          "effective_from",
          "effective_to",
          "last_confirmed_at",
          "document"
        ],
        "properties": {
          "provider": {
            "type": "string",
            "pattern": "^[a-z][a-z0-9-]*$",
            "description": "Provider ID, for example `e2b`."
          },
          "version": {
            "type": "string",
            "pattern": "^[a-z][a-z0-9-]*@[0-9]{4}-[0-9]{2}-[0-9]{2}(-[0-9]{6}Z)?$",
            "description": "The ID every cost names, for example `e2b@2026-10-01`, or `modal@2026-10-03-130908Z` when a provider has several versions in one day."
          },
          "effective_from": {
            "type": "string",
            "format": "date-time",
            "description": "When this version's prices start applying."
          },
          "effective_to": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When a later version took over; null for the version in effect now."
          },
          "last_confirmed_at": {
            "type": "string",
            "format": "date-time",
            "description": "When BoxRouter last read the provider's pricing page and found these prices unchanged."
          },
          "document": {
            "$ref": "#/components/schemas/PriceVersionDocument",
            "description": "The price version itself: unit rates, meter rules, the pages they were read from, with\nverbatim quotes, exclusions and open questions. Its structure follows the\nprice-version schema included in this API contract.\nNever changes once the version is live; a correction is a new version.\n"
          }
        }
      },
      "PriceVersionDocument": {
        "title": "Price version",
        "description": "What one provider charged from one date: unit rates, how each is metered, the pages they were read from, what the list leaves out and what is still unknown. Rates are decimal strings, never JSON numbers. A rate that is absent was not published, which is not the same as free: a published free rate is `\"0\"`. Stored status, effective_to, first_seen_at, last_confirmed_at and content_hash belong to the database, not to this document.",
        "type": "object",
        "additionalProperties": false,
        "required": [
          "provider",
          "version",
          "effective_from",
          "retrieved_at",
          "sources",
          "classes",
          "exclusions",
          "open_questions"
        ],
        "properties": {
          "provider": {
            "type": "string",
            "pattern": "^[a-z][a-z0-9-]*$"
          },
          "version": {
            "description": "The id every cost names: the provider, an @, and the UTC date the version was read, for example e2b@2026-10-20-061802Z. If a provider gets more than one version on one day, append the UTC time as HHMMSSZ, for example modal@2026-10-20-061900Z. The provider part equals `provider`.",
            "type": "string",
            "pattern": "^[a-z][a-z0-9-]*@[0-9]{4}-[0-9]{2}-[0-9]{2}(?:-([01][0-9]|2[0-3])[0-5][0-9][0-5][0-9]Z)?$"
          },
          "effective_from": {
            "description": "When this price starts applying: the provider's announced date if it gave one, else when it was first seen.",
            "$ref": "#/components/schemas/PricingTimestamp"
          },
          "retrieved_at": {
            "description": "When the pages below were read.",
            "$ref": "#/components/schemas/PricingTimestamp"
          },
          "boundary": {
            "description": "Legacy: where billing starts and ends, kept so documents published before 0.2 stay byte-identical. Code ignores it; the provider's billing.yaml is the source.",
            "$ref": "#/components/schemas/PriceVersionDocumentBoundary"
          },
          "supersedes": {
            "description": "Earlier price version ids corrected by this document. Selectors ignore these versions when the bundled price files include this document.",
            "type": "array",
            "uniqueItems": true,
            "items": {
              "$ref": "#/components/schemas/PriceVersionDocumentVersion"
            }
          },
          "month_hours": {
            "description": "The price version's hours per calendar month for monthly rates, such as 730 for 365/12 days.",
            "$ref": "#/components/schemas/PriceVersionDocumentPositiveDecimal"
          },
          "snapshot_storage": {
            "description": "Independent retained snapshot storage price; absent means unpriced. A disk rate proxy must say so explicitly.",
            "type": "object",
            "additionalProperties": false,
            "required": [
              "usd",
              "per",
              "rate_source",
              "source_url",
              "checked_at"
            ],
            "properties": {
              "usd": {
                "$ref": "#/components/schemas/PriceVersionDocumentPositiveDecimal"
              },
              "per": {
                "type": "string",
                "enum": [
                  "gb-month",
                  "gib-month",
                  "gib-hour"
                ],
                "x-boxrouter-open-enum": true
              },
              "rate_source": {
                "enum": [
                  "published_snapshot_rate",
                  "published_disk_rate_proxy"
                ]
              },
              "source_url": {
                "type": "string",
                "pattern": "^https?://[^\\s]+$"
              },
              "checked_at": {
                "$ref": "#/components/schemas/PricingTimestamp"
              },
              "note": {
                "type": "string",
                "minLength": 1
              }
            }
          },
          "image_storage": {
            "description": "Independent price of storing a deployment image the provider keeps for fast, repeatable creation; absent means unpriced. Not a sandbox's own cost: no usage record carries image size.",
            "type": "object",
            "additionalProperties": false,
            "required": [
              "usd",
              "per",
              "rate_source",
              "source_url",
              "checked_at"
            ],
            "properties": {
              "usd": {
                "$ref": "#/components/schemas/PriceVersionDocumentPositiveDecimal"
              },
              "per": {
                "type": "string",
                "enum": [
                  "gb-month",
                  "gib-month"
                ],
                "x-boxrouter-open-enum": true
              },
              "rate_source": {
                "const": "published_image_rate"
              },
              "source_url": {
                "type": "string",
                "pattern": "^https?://[^\\s]+$"
              },
              "checked_at": {
                "$ref": "#/components/schemas/PricingTimestamp"
              },
              "note": {
                "type": "string",
                "minLength": 1
              }
            }
          },
          "volume_storage": {
            "description": "Independent price of a provider volume, billed on its provisioned size for as long as it exists; absent means unpriced. Not a sandbox's own cost: no usage record carries volume size.",
            "type": "object",
            "additionalProperties": false,
            "required": [
              "usd",
              "per",
              "rate_source",
              "source_url",
              "checked_at"
            ],
            "properties": {
              "usd": {
                "$ref": "#/components/schemas/PriceVersionDocumentPositiveDecimal"
              },
              "per": {
                "type": "string",
                "enum": [
                  "gb-month",
                  "gib-month"
                ],
                "x-boxrouter-open-enum": true
              },
              "rate_source": {
                "const": "published_volume_rate"
              },
              "source_url": {
                "type": "string",
                "pattern": "^https?://[^\\s]+$"
              },
              "checked_at": {
                "$ref": "#/components/schemas/PricingTimestamp"
              },
              "included_gb": {
                "description": "Volume storage the provider includes before the rate applies, in included_unit (Modal: 1 TiB a month, written 1024 GiB).",
                "$ref": "#/components/schemas/PriceVersionDocumentPositiveDecimal"
              },
              "included_unit": {
                "const": "GiB"
              },
              "note": {
                "type": "string",
                "minLength": 1
              }
            },
            "dependentRequired": {
              "included_gb": [
                "included_unit"
              ],
              "included_unit": [
                "included_gb"
              ]
            }
          },
          "sources": {
            "description": "The pages the rates and rules were read from, each with a verbatim quote.",
            "type": "array",
            "minItems": 1,
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "url",
                "quote"
              ],
              "properties": {
                "url": {
                  "type": "string",
                  "pattern": "^https?://[^\\s]+$"
                },
                "quote": {
                  "type": "string",
                  "minLength": 1
                }
              }
            }
          },
          "classes": {
            "description": "One rate set per class or runtime the provider prices differently (Modal's gVisor and VM, a Daytona class). Exactly one is the default, which applies when a usage record names no class. Class names are unique.",
            "type": "array",
            "minItems": 1,
            "items": {
              "$ref": "#/components/schemas/PriceVersionDocumentClass"
            },
            "contains": {
              "type": "object",
              "required": [
                "default"
              ]
            },
            "minContains": 1,
            "maxContains": 1
          },
          "exclusions": {
            "description": "Charges outside a sandbox's own cost that the rates do not cover: plan fees, concurrency add-ons, credits, storage that is not priced from a sandbox's size.",
            "type": "array",
            "items": {
              "type": "string",
              "minLength": 1
            }
          },
          "coverage": {
            "description": "Every billable charge of a managed sandbox, one entry per kind, each stated as `in_quote`, `not_billed` or `unbounded`. `reservation_quote` returns `bounded` only when every kind is stated and none of cpu, memory or disk is `unbounded`; a missing kind makes the quote `unknown`, and so does a version without this block. Kinds: cpu, memory, disk, creation, egress, snapshot_storage, image_storage, volume_storage, requests (per-request or per-use charges such as starts, proxies and drive reads).",
            "type": "object",
            "additionalProperties": false,
            "properties": {
              "cpu": {
                "$ref": "#/components/schemas/PriceVersionDocumentCoverageEntry"
              },
              "memory": {
                "$ref": "#/components/schemas/PriceVersionDocumentCoverageEntry"
              },
              "disk": {
                "$ref": "#/components/schemas/PriceVersionDocumentCoverageEntry"
              },
              "creation": {
                "$ref": "#/components/schemas/PriceVersionDocumentCoverageEntry"
              },
              "egress": {
                "$ref": "#/components/schemas/PriceVersionDocumentCoverageEntry"
              },
              "snapshot_storage": {
                "$ref": "#/components/schemas/PriceVersionDocumentCoverageEntry"
              },
              "image_storage": {
                "$ref": "#/components/schemas/PriceVersionDocumentCoverageEntry"
              },
              "volume_storage": {
                "$ref": "#/components/schemas/PriceVersionDocumentCoverageEntry"
              },
              "requests": {
                "$ref": "#/components/schemas/PriceVersionDocumentCoverageEntry"
              }
            }
          },
          "open_questions": {
            "description": "What the pages leave unclear, so a reader knows which rule is an assumption.",
            "type": "array",
            "items": {
              "type": "string",
              "minLength": 1
            }
          }
        }
      },
      "PriceVersionDocumentBoundary": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "start",
          "end",
          "checked"
        ],
        "properties": {
          "start": {
            "enum": [
              "create_sent",
              "create_returned",
              "destroy_sent",
              "destroy_returned",
              "provider",
              "unknown"
            ]
          },
          "end": {
            "enum": [
              "create_sent",
              "create_returned",
              "destroy_sent",
              "destroy_returned",
              "provider",
              "unknown"
            ]
          },
          "checked": {
            "type": "boolean"
          },
          "evidence": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1
          }
        },
        "allOf": [
          {
            "if": {
              "properties": {
                "checked": {
                  "const": true
                }
              },
              "required": [
                "checked"
              ]
            },
            "then": {
              "required": [
                "evidence"
              ],
              "properties": {
                "evidence": {
                  "type": "string",
                  "minLength": 1
                }
              }
            }
          }
        ]
      },
      "PriceVersionDocumentVersion": {
        "description": "The id every cost names: the provider, an @, and the UTC date the version was read, for example e2b@2026-10-20-061802Z. If a provider gets more than one version on one day, append the UTC time as HHMMSSZ, for example modal@2026-10-20-061900Z. The provider part equals `provider`.",
        "type": "string",
        "pattern": "^[a-z][a-z0-9-]*@[0-9]{4}-[0-9]{2}-[0-9]{2}(?:-([01][0-9]|2[0-3])[0-5][0-9][0-5][0-9]Z)?$"
      },
      "PriceVersionDocumentPositiveDecimal": {
        "description": "A decimal string greater than zero.",
        "type": "string",
        "pattern": "^(0\\.[0-9]*[1-9][0-9]*|[1-9][0-9]*(\\.[0-9]+)?)$"
      },
      "PriceVersionDocumentClass": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "name",
          "rates",
          "meter"
        ],
        "properties": {
          "name": {
            "type": "string",
            "pattern": "^[a-z0-9][a-z0-9._-]*$"
          },
          "default": {
            "description": "Present, and true, on the default class only.",
            "const": true
          },
          "covers": {
            "description": "The spec classes this rate set prices (Modal's default covers default and vm; Daytona's on-demand covers container and vm). A usage record's class names a spec class. Absent, the class covers only the spec class of its own name. No spec class is covered by two classes of one version.",
            "type": "array",
            "minItems": 1,
            "uniqueItems": true,
            "items": {
              "type": "string",
              "pattern": "^[a-z0-9][a-z0-9._-]*$"
            }
          },
          "derived_from": {
            "description": "Rates this class takes from another class of the same version times a factor the provider publishes, where it publishes no unit rate of its own (Agent37's VM compute is 2.5x its default rate). Each named rate equals that class's rate times the factor, and a source quote states the factor.",
            "type": "object",
            "additionalProperties": false,
            "required": [
              "class",
              "factor",
              "rates"
            ],
            "properties": {
              "class": {
                "type": "string",
                "pattern": "^[a-z0-9][a-z0-9._-]*$"
              },
              "factor": {
                "$ref": "#/components/schemas/PriceVersionDocumentPositiveDecimal"
              },
              "rates": {
                "type": "array",
                "minItems": 1,
                "uniqueItems": true,
                "items": {
                  "type": "string"
                }
              }
            }
          },
          "rates": {
            "$ref": "#/components/schemas/PriceVersionDocumentRates"
          },
          "meter": {
            "$ref": "#/components/schemas/PriceVersionDocumentMeter"
          },
          "region_multipliers": {
            "description": "A multiplier on every rate of this class for sandboxes in the named region (Modal's 1.15 for a broad region). A region that is not listed is charged at the base rate.",
            "type": "object",
            "minProperties": 1,
            "propertyNames": {
              "pattern": "^[a-z0-9][a-z0-9._-]*$"
            },
            "additionalProperties": {
              "$ref": "#/components/schemas/PriceVersionDocumentPositiveDecimal"
            }
          }
        }
      },
      "PriceVersionDocumentRates": {
        "description": "Unit rates, each optional. A rate is a price and the unit it is a price per, as the provider publishes it.",
        "type": "object",
        "additionalProperties": false,
        "minProperties": 1,
        "properties": {
          "cpu": {
            "$ref": "#/components/schemas/PriceVersionDocumentCpuRate"
          },
          "memory": {
            "$ref": "#/components/schemas/PriceVersionDocumentGibRate"
          },
          "disk": {
            "$ref": "#/components/schemas/PriceVersionDocumentGibRate"
          },
          "gpu": {
            "description": "Rates by GPU model, keyed by gpu-registry identifiers.",
            "$ref": "#/components/schemas/PriceVersionDocumentGpuRates"
          },
          "machine": {
            "$ref": "#/components/schemas/PriceVersionDocumentMachineRates"
          },
          "creation": {
            "$ref": "#/components/schemas/PriceVersionDocumentCreationRate"
          },
          "egress": {
            "$ref": "#/components/schemas/PriceVersionDocumentEgressRate"
          },
          "snapshot_storage": {
            "$ref": "#/components/schemas/PriceVersionDocumentStorageRate"
          }
        }
      },
      "PriceVersionDocumentCpuRate": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "usd",
          "per"
        ],
        "properties": {
          "usd": {
            "$ref": "#/components/schemas/PricingDecimal"
          },
          "per": {
            "type": "string",
            "description": "A month is 730 hours, as providers that price per month define it.",
            "enum": [
              "vcpu-second",
              "vcpu-hour",
              "vcpu-month",
              "core-second",
              "core-hour"
            ],
            "x-boxrouter-open-enum": true
          },
          "size_per_unit": {
            "description": "vCPUs one core covers. Required for a core unit, which is not a vCPU (Modal's physical core), and absent for a vCPU unit.",
            "$ref": "#/components/schemas/PriceVersionDocumentPositiveDecimal"
          }
        },
        "if": {
          "properties": {
            "per": {
              "enum": [
                "core-second",
                "core-hour"
              ]
            }
          },
          "required": [
            "per"
          ]
        },
        "then": {
          "required": [
            "size_per_unit"
          ]
        },
        "else": {
          "not": {
            "required": [
              "size_per_unit"
            ]
          }
        }
      },
      "PriceVersionDocumentGibRate": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "usd",
          "per"
        ],
        "properties": {
          "usd": {
            "$ref": "#/components/schemas/PricingDecimal"
          },
          "per": {
            "type": "string",
            "description": "A month is 730 hours, as providers that price per month define it.",
            "enum": [
              "gib-second",
              "gib-hour",
              "gib-month",
              "gb-second",
              "gb-hour",
              "gb-month"
            ],
            "x-boxrouter-open-enum": true
          },
          "size_per_unit": {
            "description": "GiB one GB covers: 1 where the provider's GB is read as a GiB, as Vercel's and Blaxel's examples do. Required for a GB unit and absent for a GiB unit.",
            "$ref": "#/components/schemas/PriceVersionDocumentPositiveDecimal"
          }
        },
        "if": {
          "properties": {
            "per": {
              "enum": [
                "gb-second",
                "gb-hour",
                "gb-month"
              ]
            }
          },
          "required": [
            "per"
          ]
        },
        "then": {
          "required": [
            "size_per_unit"
          ]
        },
        "else": {
          "not": {
            "required": [
              "size_per_unit"
            ]
          }
        }
      },
      "PriceVersionDocumentGpuRates": {
        "type": "object",
        "minProperties": 1,
        "propertyNames": {
          "pattern": "^[a-z][a-z0-9-]*:[a-z0-9][a-z0-9-]*$"
        },
        "additionalProperties": {
          "$ref": "#/components/schemas/PriceVersionDocumentGpuRate"
        }
      },
      "PriceVersionDocumentGpuRate": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "usd",
          "per"
        ],
        "properties": {
          "usd": {
            "$ref": "#/components/schemas/PricingDecimal"
          },
          "per": {
            "type": "string",
            "enum": [
              "gpu-second",
              "gpu-hour"
            ],
            "x-boxrouter-open-enum": true
          }
        }
      },
      "PriceVersionDocumentMachineRates": {
        "description": "Flat per-size machine rates, keyed by the provider's own size name. Each entry prices one published bundle: a sandbox whose size matches the entry's cpu and memory_gib is billed the flat rate while the meter runs it. A sandbox size that matches no entry has no machine price. Used where the provider sells a bundle with no published per-unit split.",
        "type": "object",
        "minProperties": 1,
        "propertyNames": {
          "pattern": "^[a-z0-9][a-z0-9._-]*$"
        },
        "additionalProperties": {
          "$ref": "#/components/schemas/PriceVersionDocumentMachineRate"
        }
      },
      "PriceVersionDocumentMachineRate": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "usd",
          "per",
          "cpu",
          "memory_gib"
        ],
        "properties": {
          "usd": {
            "$ref": "#/components/schemas/PricingDecimal"
          },
          "per": {
            "type": "string",
            "enum": [
              "machine-second",
              "machine-hour"
            ],
            "x-boxrouter-open-enum": true
          },
          "cpu": {
            "description": "vCPUs the published size gives.",
            "$ref": "#/components/schemas/PriceVersionDocumentPositiveDecimal"
          },
          "memory_gib": {
            "description": "GiB of memory the published size gives; where the provider quotes GB it is read as a GiB.",
            "$ref": "#/components/schemas/PriceVersionDocumentPositiveDecimal"
          },
          "note": {
            "type": "string",
            "minLength": 1
          }
        }
      },
      "PriceVersionDocumentCreationRate": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "usd",
          "per"
        ],
        "properties": {
          "usd": {
            "$ref": "#/components/schemas/PricingDecimal"
          },
          "per": {
            "type": "string",
            "enum": [
              "creation",
              "million-creations"
            ],
            "x-boxrouter-open-enum": true
          }
        }
      },
      "PriceVersionDocumentEgressRate": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "usd",
          "per"
        ],
        "properties": {
          "usd": {
            "$ref": "#/components/schemas/PricingDecimal"
          },
          "per": {
            "type": "string",
            "description": "gib is 2^30 bytes; gb is 10^9 bytes.",
            "enum": [
              "gib",
              "gb"
            ],
            "x-boxrouter-open-enum": true
          }
        }
      },
      "PriceVersionDocumentStorageRate": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "usd",
          "per"
        ],
        "properties": {
          "usd": {
            "$ref": "#/components/schemas/PricingDecimal"
          },
          "per": {
            "const": "gb-month"
          }
        }
      },
      "PriceVersionDocumentMeter": {
        "description": "How each time-billed resource is metered. A resource with a rate and no meter rule cannot be priced.",
        "type": "object",
        "additionalProperties": false,
        "patternProperties": {
          "^(cpu|gpu|machine)$": {
            "$ref": "#/components/schemas/PriceVersionDocumentTimeMeter"
          },
          "^memory$": {
            "$ref": "#/components/schemas/PriceVersionDocumentMemoryMeter"
          },
          "^disk$": {
            "$ref": "#/components/schemas/PriceVersionDocumentDiskMeter"
          },
          "^snapshot_storage$": {
            "$ref": "#/components/schemas/PriceVersionDocumentStorageMeter"
          }
        }
      },
      "PriceVersionDocumentTimeMeter": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "basis",
          "billed_states"
        ],
        "properties": {
          "basis": {
            "description": "allocated: the size the sandbox has. active: only while the resource is in use (Vercel's CPU). larger_of_request_and_use: whichever is greater (Modal).",
            "enum": [
              "allocated",
              "active",
              "larger_of_request_and_use"
            ]
          },
          "billed_states": {
            "description": "The sandbox states in which this resource is charged.",
            "type": "array",
            "minItems": 1,
            "uniqueItems": true,
            "items": {
              "enum": [
                "running",
                "paused",
                "stopped"
              ]
            }
          },
          "minimum_seconds": {
            "description": "The least that is charged for each period in a billed state.",
            "type": "integer",
            "minimum": 1
          },
          "increment_seconds": {
            "description": "Each period in a billed state is rounded up to a multiple of this.",
            "type": "integer",
            "minimum": 1
          },
          "free_quantity": {
            "description": "An allowance that is free for every sandbox, in the resource's size unit (vCPUs, GiB, GPUs). An allowance shared across an account is an exclusion, not a meter rule.",
            "$ref": "#/components/schemas/PricingDecimal"
          }
        }
      },
      "PriceVersionDocumentMemoryMeter": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "basis",
          "billed_states"
        ],
        "properties": {
          "basis": {
            "description": "allocated: the size the sandbox has; active: only while the resource is in use; larger_of_request_and_use: whichever is greater.",
            "enum": [
              "allocated",
              "active",
              "larger_of_request_and_use"
            ]
          },
          "billed_states": {
            "type": "array",
            "minItems": 1,
            "uniqueItems": true,
            "items": {
              "enum": [
                "running",
                "paused",
                "stopped"
              ]
            }
          },
          "minimum_seconds": {
            "type": "integer",
            "minimum": 1
          },
          "increment_seconds": {
            "type": "integer",
            "minimum": 1
          },
          "free_quantity": {
            "$ref": "#/components/schemas/PricingDecimal"
          },
          "memory_steps_mib": {
            "description": "Discrete billed memory sizes in MiB. A request rounds up to the next listed size; a request above every tier has no price.",
            "type": "array",
            "minItems": 1,
            "uniqueItems": true,
            "items": {
              "type": "integer",
              "minimum": 1
            }
          }
        }
      },
      "PriceVersionDocumentDiskMeter": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "basis",
          "billed_states"
        ],
        "properties": {
          "basis": {
            "enum": [
              "allocated",
              "active",
              "larger_of_request_and_use"
            ]
          },
          "billed_states": {
            "type": "array",
            "minItems": 1,
            "uniqueItems": true,
            "items": {
              "enum": [
                "running",
                "paused",
                "stopped"
              ]
            }
          },
          "minimum_seconds": {
            "type": "integer",
            "minimum": 1
          },
          "increment_seconds": {
            "type": "integer",
            "minimum": 1
          },
          "free_quantity": {
            "$ref": "#/components/schemas/PricingDecimal"
          },
          "disk_gib_per_memory_gib": {
            "description": "Set where the provider charges disk by raising the memory it bills: how many GiB of disk count as one GiB of memory (Modal's 20). The class then has no disk rate.",
            "$ref": "#/components/schemas/PriceVersionDocumentPositiveDecimal"
          }
        }
      },
      "PriceVersionDocumentStorageMeter": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "billed_states"
        ],
        "properties": {
          "billed_states": {
            "type": "array",
            "minItems": 1,
            "uniqueItems": true,
            "items": {
              "enum": [
                "running",
                "paused",
                "stopped"
              ]
            }
          }
        }
      },
      "PriceVersionDocumentCoverageEntry": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "treatment",
          "source",
          "note"
        ],
        "properties": {
          "treatment": {
            "description": "`in_quote`: priced into a reservation quote (time-bounded, or the creation fee). `not_billed`: the provider does not bill it on managed sandboxes. `unbounded`: billable or possibly billable, but no ceiling follows from a size and a duration (egress, retained storage, request- or use-based); it is outside the quote and settled from the provider's own cost.",
            "enum": [
              "in_quote",
              "not_billed",
              "unbounded"
            ]
          },
          "source": {
            "description": "Where the treatment was read: a URL listed in `sources`, or a repo-relative path to committed evidence under `providers/`.",
            "type": "string",
            "minLength": 1
          },
          "note": {
            "description": "The reason, in one sentence. For a charge the provider does not publish, say so: unpublished is never free.",
            "type": "string",
            "minLength": 1
          }
        }
      },
      "ProviderPage": {
        "type": "object",
        "required": [
          "data"
        ],
        "description": "The routes this workspace can use as written or with the listed `request_overrides`, one\nentry per connected account or managed supply. Each entry has the gates, resources, attested\nfacts and lifetime that `match` reports for the route, from the same adapter declarations.\nOverrides are create fields to add for that route; they are never merged across routes.\n",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EligibleRoute"
            }
          }
        }
      }
    },
    "responses": {
      "Error": {
        "description": "Structured error. `retry` says whether to send the call again (`now`, `after_fix`, `inspect` or `never`) and `retry_after_seconds` how long to wait first. Unowned and unknown resource IDs both return 404. Admission overload returns 503 with code overloaded, outcome not_started and Retry-After. It reserves no operation and dispatches no provider work. Shared workspace/provider admission budgets return 429 with code rate_limited, outcome not_started and Retry-After. An incomplete request body can return 408 request_timeout before dispatch. Durable-state failures return 503 database_unavailable with outcome unknown; do not infer that execution did not occur. A read (GET or HEAD) that meets the same failure changed nothing: its message says the state is temporarily unavailable, and it is safe to repeat. A provider that cannot be reached when a create is prepared returns 502 provider_error with outcome not_started; nothing was created, and the create can be retried with the same Idempotency-Key or sent to another provider with `providers`.\nNative errors are sanitized; upstream credentials, request bodies and\nanother workspace's metadata are never included. Server-Timing is present only when the response reached Dispatcher or held-response preparation; an earlier response, including pre-Dispatcher admission overload, may omit it.\n",
        "headers": {
          "X-Request-ID": {
            "$ref": "#/components/headers/RequestId"
          },
          "Server-Timing": {
            "$ref": "#/components/headers/ServerTiming"
          },
          "Retry-After": {
            "description": "Seconds before retrying an eligible read; not permission to replay a mutation.",
            "schema": {
              "type": "integer",
              "minimum": 0
            }
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ApiErrorResponse"
            }
          }
        }
      }
    },
    "headers": {
      "RequestId": {
        "description": "Server-generated correlation identifier; contains no credentials or payloads.",
        "schema": {
          "type": "string"
        }
      },
      "ServerTiming": {
        "description": "Durations of server-side phases, for diagnosing slow requests. Phase names are not stable\nand may change.\n",
        "schema": {
          "type": "string"
        },
        "x-boxrouter-server-timing": {
          "version": 1,
          "unit": "ms",
          "serviceAggregateMetric": "service",
          "maxHeaderBytes": 8192,
          "maxOperationRows": 32,
          "decimalPlaces": 3,
          "safeNamePattern": "^[A-Za-z0-9_.:-]{1,64}$",
          "aggregates": [
            {
              "metric": "service",
              "fieldStem": "cloud"
            },
            {
              "metric": "database",
              "fieldStem": "database"
            },
            {
              "metric": "code",
              "fieldStem": "code"
            },
            {
              "metric": "provider_connect",
              "fieldStem": "provider_connect"
            },
            {
              "metric": "provider_wait",
              "fieldStem": "provider_wait"
            },
            {
              "metric": "accept",
              "fieldStem": "accept"
            },
            {
              "metric": "queue",
              "fieldStem": "queue"
            },
            {
              "metric": "admission",
              "fieldStem": "admission"
            },
            {
              "metric": "encode",
              "fieldStem": "encode"
            }
          ],
          "aggregateGrammar": {
            "duration": {
              "parameter": "dur",
              "type": "number",
              "finite": true,
              "minimum": 0
            },
            "descriptionParameter": "desc",
            "unknownDescription": "unknown",
            "missingMeans": "unreported"
          },
          "operationGrammar": {
            "metric": "op",
            "nameParameter": "desc",
            "namePattern": "safeNamePattern",
            "start": {
              "parameter": "start",
              "type": "number",
              "finite": true,
              "sign": "signed",
              "relativeTo": "recorderWindow"
            },
            "duration": {
              "parameter": "dur",
              "type": "number",
              "finite": true,
              "minimum": 0
            },
            "outcomeParameter": "outcome",
            "outcomes": [
              "returned",
              "raised"
            ],
            "requiresAggregateDependencyUnion": false
          },
          "omissionGrammar": {
            "metric": "op-omitted",
            "count": {
              "parameter": "desc",
              "type": "integer",
              "minimum": 0
            },
            "duration": {
              "parameter": "dur",
              "type": "number",
              "finite": true,
              "minimum": 0,
              "sumOf": "knownOmittedMeasuredRows"
            },
            "requiresAggregateDependencyUnion": false
          },
          "coverageGrammar": {
            "metric": "op-coverage",
            "descriptionParameter": "desc",
            "unknownValue": "unknown",
            "absentState": "unreported",
            "states": [
              "unknown",
              "unreported"
            ],
            "absenceImpliesCompleteness": false
          }
        }
      }
    },
    "parameters": {
      "LaunchIdempotencyKey": {
        "name": "Idempotency-Key",
        "in": "header",
        "required": true,
        "description": "Unique identifier for this logical launch. Reuse it with the identical body to reconcile an uncertain response.",
        "schema": {
          "type": "string",
          "minLength": 1,
          "maxLength": 128,
          "pattern": "^[^\\u0000]+$"
        }
      },
      "Cursor": {
        "name": "cursor",
        "in": "query",
        "description": "Opaque cursor from the preceding page; scoped to the original workspace and query.",
        "schema": {
          "type": "string",
          "minLength": 1,
          "maxLength": 128,
          "pattern": "^[^\\u0000]*$"
        }
      },
      "Limit": {
        "name": "limit",
        "in": "query",
        "description": "Maximum number of records to return.",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 100,
          "default": 20
        }
      },
      "InstallationId": {
        "name": "installation_id",
        "in": "path",
        "required": true,
        "description": "Stable GitHub App installation ID, represented as a string to avoid integer-width assumptions.",
        "schema": {
          "type": "string",
          "minLength": 1,
          "maxLength": 128,
          "pattern": "^[^\\u0000]*$"
        }
      },
      "Csrf": {
        "name": "X-CSRF-Token",
        "in": "header",
        "required": true,
        "schema": {
          "type": "string"
        },
        "description": "Session-bound CSRF token; a matching configured Origin header is also required."
      },
      "IdempotencyKey": {
        "name": "Idempotency-Key",
        "in": "header",
        "description": "Optional for this operation. Preserve the same stable identifier when retrying an uncertain response; never reuse it for new work. If omitted where allowed, Cloud generates a request-scoped key that cannot reconcile a later retry. Do not include credentials or payloads.",
        "schema": {
          "$ref": "#/components/schemas/IdempotencyKeyValue"
        }
      },
      "InstallationQuery": {
        "name": "installation_id",
        "in": "query",
        "required": true,
        "description": "Workspace-linked GitHub App installation whose repository access is being listed.",
        "schema": {
          "type": "string",
          "minLength": 1,
          "maxLength": 128,
          "pattern": "^[^\\u0000]*$"
        }
      },
      "RepositoryId": {
        "name": "repository_id",
        "in": "path",
        "required": true,
        "description": "Stable GitHub repository ID bound to this workspace; owner/name is not an identifier.",
        "schema": {
          "type": "string",
          "minLength": 1,
          "maxLength": 128,
          "pattern": "^[^\\u0000]*$"
        }
      },
      "CsrfBrowserOnly": {
        "name": "X-CSRF-Token",
        "in": "header",
        "required": false,
        "schema": {
          "type": "string"
        },
        "description": "Session-bound CSRF token. Required for browser-session calls, together with a matching configured Origin header; omit it when calling with an API key."
      },
      "PolicyId": {
        "name": "policy_id",
        "in": "path",
        "required": true,
        "description": "Workspace-owned Actions policy ID.",
        "schema": {
          "type": "string",
          "minLength": 1,
          "maxLength": 128,
          "pattern": "^[^\\u0000]*$"
        }
      },
      "IfMatch": {
        "name": "If-Match",
        "in": "header",
        "required": true,
        "description": "Strong ETag returned by the latest read; a stale value conflicts without changing the resource.",
        "schema": {
          "type": "string",
          "minLength": 1,
          "maxLength": 256,
          "pattern": "^[^\\u0000]*$"
        }
      },
      "RunId": {
        "name": "run_id",
        "in": "path",
        "required": true,
        "description": "Workspace-owned BoxRouter workflow-run projection ID, not a GitHub run ID.",
        "schema": {
          "type": "string",
          "minLength": 1,
          "maxLength": 128,
          "pattern": "^[^\\u0000]*$"
        }
      },
      "JobId": {
        "name": "job_id",
        "in": "path",
        "required": true,
        "description": "Workspace-owned BoxRouter job projection ID, not a GitHub job ID.",
        "schema": {
          "type": "string",
          "minLength": 1,
          "maxLength": 128,
          "pattern": "^[^\\u0000]*$"
        }
      },
      "PlacementId": {
        "name": "placement_id",
        "in": "path",
        "required": true,
        "description": "Workspace-owned BoxRouter placement ID.",
        "schema": {
          "type": "string",
          "minLength": 1,
          "maxLength": 128,
          "pattern": "^[^\\u0000]*$"
        }
      },
      "SandboxId": {
        "name": "sandbox_id",
        "in": "path",
        "required": true,
        "description": "Workspace-owned BoxRouter sandbox ID, not an upstream ID.",
        "schema": {
          "type": "string",
          "minLength": 1,
          "pattern": "^[^\\u0000]*$"
        }
      },
      "ProcessId": {
        "name": "process_id",
        "in": "path",
        "required": true,
        "description": "Durable BoxRouter process ID owned by the addressed sandbox and workspace.",
        "schema": {
          "type": "string",
          "minLength": 1
        }
      },
      "RequiredIdempotencyKey": {
        "name": "Idempotency-Key",
        "in": "header",
        "required": true,
        "description": "Required caller-generated identifier for one logical mutation. Preserve it when retrying an uncertain response; never reuse it for new work. Do not include credentials or payloads.",
        "schema": {
          "$ref": "#/components/schemas/IdempotencyKeyValue"
        }
      },
      "TerminalId": {
        "name": "terminal_id",
        "in": "path",
        "required": true,
        "description": "BoxRouter terminal ID owned by the addressed sandbox and workspace.",
        "schema": {
          "type": "string",
          "minLength": 1
        }
      },
      "PreviewId": {
        "name": "preview_id",
        "in": "path",
        "required": true,
        "description": "Workspace-owned BoxRouter preview ID, as the open returned it.",
        "schema": {
          "type": "string",
          "minLength": 1,
          "maxLength": 128,
          "pattern": "^[^\\u0000]*$"
        }
      },
      "AccountId": {
        "name": "account_id",
        "in": "path",
        "required": true,
        "description": "BoxRouter connected-account ID, scoped to this workspace.",
        "schema": {
          "type": "string",
          "minLength": 1,
          "pattern": "^[^\\u0000]*$"
        }
      },
      "VolumeId": {
        "name": "volume_id",
        "in": "path",
        "required": true,
        "schema": {
          "$ref": "#/components/schemas/VolumeId"
        }
      },
      "UploadId": {
        "name": "upload_id",
        "in": "path",
        "required": true,
        "description": "ID of the open volume file upload.",
        "schema": {
          "$ref": "#/components/schemas/UploadId"
        }
      },
      "TransferIdempotencyKey": {
        "name": "Idempotency-Key",
        "in": "header",
        "required": true,
        "description": "Unique identifier for this one file transfer call. Reuse it with the identical request to reconcile an uncertain response; never reuse it for new work.",
        "schema": {
          "$ref": "#/components/schemas/IdempotencyKeyValue"
        }
      },
      "SandboxUploadId": {
        "name": "upload_id",
        "in": "path",
        "required": true,
        "description": "ID of the open sandbox file upload.",
        "schema": {
          "$ref": "#/components/schemas/SandboxUploadId"
        }
      },
      "Path": {
        "name": "path",
        "in": "query",
        "required": true,
        "description": "Absolute path inside the sandbox, encoded as a query value.",
        "schema": {
          "type": "string",
          "minLength": 1,
          "pattern": "^/[^\\u0000]*$"
        }
      }
    }
  }
}
