{
  "openapi": "3.1.0",
  "info": {
    "title": "Promigence API",
    "version": "0.0.1",
    "summary": "Verified, reproducible, forkable sandboxes for agents. Billed per second.",
    "description": "The Promigence API. Every route, schema and error code here is generated from the service's own types and error table, so this document and the wire cannot disagree.",
    "contact": {
      "name": "Promigence",
      "email": "support@promigence.ai"
    }
  },
  "servers": [
    {
      "url": "https://api.promigence.ai"
    }
  ],
  "tags": [
    {
      "name": "Meta"
    },
    {
      "name": "Snapshots"
    },
    {
      "name": "GitHub"
    },
    {
      "name": "GitLab"
    },
    {
      "name": "Runs"
    },
    {
      "name": "Sandboxes"
    },
    {
      "name": "Execs"
    },
    {
      "name": "Files"
    },
    {
      "name": "Ports and terminal"
    },
    {
      "name": "Secrets"
    },
    {
      "name": "Organisation"
    },
    {
      "name": "Billing"
    },
    {
      "name": "Keys and sign-in"
    }
  ],
  "security": [
    {
      "apiKey": []
    }
  ],
  "paths": {
    "/status": {
      "get": {
        "operationId": "get_status",
        "summary": "The same data rendered as a self-contained HTML page by the API itself.",
        "tags": [
          "Meta"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/html": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "none"
      }
    },
    "/v1/auth/claim": {
      "get": {
        "operationId": "get_v1_auth_claim",
        "summary": "The page where the free credit is claimed, in a browser: the offer, the terms to accept, and the Claim button. Opened from the single-use link `POST /v1/credits/claim-link` makes (`promigence credits claim`); the link's token is the authority.",
        "tags": [
          "Keys and sign-in"
        ],
        "security": [],
        "parameters": [
          {
            "name": "t",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "none",
        "x-promigence-body": "unspecified"
      }
    },
    "/v1/auth/cli-callback": {
      "get": {
        "operationId": "get_v1_auth_cli_callback",
        "summary": "The page a browser lands on after sign-in; in headless mode it shows the code to paste back.",
        "tags": [
          "Keys and sign-in"
        ],
        "security": [],
        "parameters": [
          {
            "name": "code",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "error",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "state",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/html": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "none"
      }
    },
    "/v1/auth/cli/requests": {
      "post": {
        "operationId": "post_v1_auth_cli_requests",
        "summary": "Start `promigence login` through the console: register the sign-in request (the PKCE S256 challenge, the state, the local port the CLI listens on or none to paste the code, the computer's name and the new key's name) and get the authorize page to open for it. The page shows the signed-in person what is asking, and when and from where the request was made; it refuses a request that is more than ten minutes old or was already answered. `promigence login` does this for you.",
        "tags": [
          "Keys and sign-in"
        ],
        "security": [],
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CliRequestCreated"
                },
                "example": {
                  "authorize_url": "https://console.promigence.ai/cli/authorize?request=creq_9xQ2mL0aB7cD4eF1gH3iJ5",
                  "expires_in_s": 600,
                  "request_id": "creq_9xQ2mL0aB7cD4eF1gH3iJ5"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "413": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "none",
        "x-promigence-status": 201,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CliRequestCreate"
              },
              "example": {
                "code_challenge": "E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM",
                "code_challenge_method": "S256",
                "device": "laptop",
                "key_name": "cli@laptop",
                "port": 47815,
                "state": "st-8f2a91c4"
              }
            }
          }
        }
      }
    },
    "/v1/auth/cli/token": {
      "post": {
        "operationId": "post_v1_auth_cli_token",
        "summary": "Finish `promigence login` after you authorized the CLI in the browser: exchange the one-time code the authorize page gave the CLI, with the PKCE verifier whose S256 challenge the CLI sent there, for an API key (`api_key`, in this answer only). A code works once, for five minutes, and only with its own verifier and the redirect it was delivered to; any other attempt uses it up. `promigence login` does this for you; `GET /v1/auth/config` names the authorize page in `console_authorize_url`.",
        "tags": [
          "Keys and sign-in"
        ],
        "security": [],
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Session"
                },
                "example": {
                  "api_key": "prom_api_9f3a1c0e…",
                  "created": true,
                  "key": {
                    "access": "full",
                    "created_at": "2026-09-18T11:02:44Z",
                    "created_by": "usr_71c0de",
                    "expires_at": null,
                    "key_id": "key_2f8a11",
                    "last_used_at": "2026-09-19T09:14:02Z",
                    "minted_by": null,
                    "name": "cli",
                    "prefix": "prom_api_9f3a1c0e",
                    "revoked_at": null
                  },
                  "org": {
                    "default_spend_cap": 5,
                    "max_inflight": 20,
                    "name": "acme",
                    "org_id": "org_5c1a90",
                    "role": "owner"
                  },
                  "referral": {
                    "code": "K7QM2XPD",
                    "qualifying_plans": [],
                    "reward_usd": 50,
                    "status": "pending"
                  },
                  "trial": {
                    "credits_granted": 0,
                    "second_trial": false
                  },
                  "user": {
                    "created_at": "2026-09-18T11:02:44Z",
                    "email": "dev@example.com",
                    "email_verified": true,
                    "provider": "github",
                    "user_id": "usr_71c0de"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "413": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "none",
        "x-promigence-status": 201,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CliTokenCreate"
              },
              "example": {
                "code": "c0de",
                "code_verifier": "v3rifier-0123456789abcdefghijklmnopqrstuvwxyz"
              }
            }
          }
        }
      }
    },
    "/v1/auth/config": {
      "get": {
        "operationId": "get_v1_auth_config",
        "summary": "What `promigence login` needs to start a sign-in: the identity domain, client id and scopes, and the console page where you authorize the CLI (`console_authorize_url`, when it is offered).",
        "tags": [
          "Keys and sign-in"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthConfig"
                },
                "example": {
                  "authorize_url": "https://auth.promigence.ai/oauth2/authorize",
                  "client_id": "3f9a1c7e5b2d",
                  "console_authorize_url": "https://console.promigence.ai/cli/authorize",
                  "identity_providers": {
                    "email": "Email",
                    "github": "GitHub",
                    "google": "Google"
                  },
                  "invite_mode": false,
                  "loopback_redirect_uris": [
                    "http://localhost:8765/callback"
                  ],
                  "paste_redirect_uri": "https://api.promigence.ai/auth/cli-callback",
                  "scopes": [
                    "openid",
                    "email",
                    "profile"
                  ],
                  "token_url": "https://auth.promigence.ai/oauth2/token"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "none"
      }
    },
    "/v1/auth/invite": {
      "post": {
        "operationId": "post_v1_auth_invite",
        "summary": "Redeem an invite code for one sign-in attempt, before the sign-in starts (`promigence signup` does it for you). Only while `GET /v1/auth/config` says `invite_mode`: the attempt with the same login nonce may then create an account within `expires_in_s`. Every code that does not redeem gets the same `403 invite_invalid`; attempts are rate limited per address.",
        "tags": [
          "Keys and sign-in"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InviteRedeemed"
                },
                "example": {
                  "expires_in_s": 600,
                  "invite_mode": true
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "413": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "none",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InviteRedeem"
              },
              "example": {
                "code": "INV-EXAMPLE",
                "nonce": "n0nce"
              }
            }
          }
        }
      }
    },
    "/v1/auth/invite/release": {
      "post": {
        "operationId": "post_v1_auth_invite_release",
        "summary": "Give back the place a redeemed invite code holds for a sign-in attempt that ended without an account (it timed out or was cancelled), so the next attempt can redeem the code at once (`promigence signup` does it for you). Only the attempt's own login nonce names its hold, and a hold that already created an account is never given back. Always `200 {released}`; rate limited per address.",
        "tags": [
          "Keys and sign-in"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InviteReleased"
                },
                "example": {
                  "released": true
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "413": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "none",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InviteRelease"
              },
              "example": {
                "nonce": "n0nce"
              }
            }
          }
        }
      }
    },
    "/v1/auth/session": {
      "post": {
        "operationId": "post_v1_auth_session",
        "summary": "Exchange an identity token for a Promigence API key. The first call for an identity creates the user, the org, its free credit offer (claimed later in a browser, `POST /v1/credits/claim-link`) and the first key, in one transaction. One account per verified email address: a first sign-in whose address already has an account through another sign-in method creates nothing and is answered `409 account_exists`, naming the method to sign in with. While invite mode is on, a first sign-in whose attempt redeemed no invite code (`POST /v1/auth/invite`) creates nothing and is answered `403 invite_required`; an existing account is never asked for a code.",
        "tags": [
          "Keys and sign-in"
        ],
        "security": [
          {
            "identityToken": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Session"
                },
                "example": {
                  "api_key": "prom_api_9f3a1c0e…",
                  "created": true,
                  "key": {
                    "access": "full",
                    "created_at": "2026-09-18T11:02:44Z",
                    "created_by": "usr_71c0de",
                    "expires_at": null,
                    "key_id": "key_2f8a11",
                    "last_used_at": "2026-09-19T09:14:02Z",
                    "minted_by": null,
                    "name": "cli",
                    "prefix": "prom_api_9f3a1c0e",
                    "revoked_at": null
                  },
                  "org": {
                    "default_spend_cap": 5,
                    "max_inflight": 20,
                    "name": "acme",
                    "org_id": "org_5c1a90",
                    "role": "owner"
                  },
                  "referral": {
                    "code": "K7QM2XPD",
                    "qualifying_plans": [],
                    "reward_usd": 50,
                    "status": "pending"
                  },
                  "trial": {
                    "credits_granted": 0,
                    "second_trial": false
                  },
                  "user": {
                    "created_at": "2026-09-18T11:02:44Z",
                    "email": "dev@example.com",
                    "email_verified": true,
                    "provider": "github",
                    "user_id": "usr_71c0de"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "413": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "token",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SessionCreate"
              },
              "example": {
                "key_name": "laptop",
                "mint_key": true,
                "nonce": "n0nce"
              }
            }
          }
        }
      }
    },
    "/v1/billing": {
      "get": {
        "operationId": "get_v1_billing",
        "summary": "Plan, card on file, this month's usage, and the upcoming invoice preview.",
        "tags": [
          "Billing"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BillingStatus"
                },
                "example": {
                  "billing_enabled": true,
                  "card": {
                    "brand": "visa",
                    "last4": "4242"
                  },
                  "card_note": null,
                  "card_on_file": true,
                  "customer": true,
                  "method_check": null,
                  "notice": null,
                  "org_id": "org_5c1a90",
                  "period": {
                    "basis": "utc_calendar_month",
                    "end": "2026-10-01T00:00:00.000Z",
                    "start": "2026-09-01T00:00:00.000Z"
                  },
                  "plan": "hobby",
                  "suspend_reason": null,
                  "suspended": false,
                  "trial": {
                    "card_on_file": true,
                    "credits_available": 94.0888,
                    "credits_granted": 100,
                    "credits_remaining": 94.24,
                    "credits_reserved": 0.1512,
                    "egress_gb_cap": 20,
                    "egress_gb_used": 0.0195,
                    "egress_month": "2026-09",
                    "limits": {
                      "egress_gb_month": 20,
                      "max_concurrency": 20,
                      "max_sandbox_vcpus": 8,
                      "max_session_s": 3600,
                      "smtp": false
                    },
                    "on_trial": true,
                    "policy": {
                      "card_required_from": null,
                      "card_required_now": false,
                      "mode": "open",
                      "notice_from": null
                    }
                  },
                  "upcoming_invoice": {
                    "amount_due": 0,
                    "currency": "usd",
                    "next_payment_attempt": "2026-10-01T01:00:00Z",
                    "period_end": "2026-10-01T00:00:00Z",
                    "period_start": "2026-09-01T00:00:00Z",
                    "subtotal": 0,
                    "total": 0
                  },
                  "upcoming_invoice_error": null,
                  "usage": {
                    "billable": 0,
                    "builds": {
                      "amount": 0.5,
                      "count": 1
                    },
                    "credits_applied": 5.76,
                    "currency": "usd",
                    "egress": {
                      "amount": 0,
                      "gib": 0.0195,
                      "mib": 20
                    },
                    "other": {},
                    "sandboxes": {
                      "standard": {
                        "amount": 5.26,
                        "gib_seconds": 548576,
                        "seconds": 34286,
                        "vcpu_seconds": 274288
                      }
                    },
                    "total": 5.76,
                    "unreported_entries": 0
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key"
      }
    },
    "/v1/billing/checkout": {
      "post": {
        "operationId": "post_v1_billing_checkout",
        "summary": "Start a card-setup checkout. Adding a card keeps any trial credit you have left. Owners only (with their own key).",
        "tags": [
          "Billing"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CheckoutSession"
                },
                "example": {
                  "expires_at": "2026-09-19T10:14:02Z",
                  "mode": "setup",
                  "session_id": "cs_test_a1b2",
                  "url": "https://checkout.example/c/cs_test_a1b2"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key"
      }
    },
    "/v1/billing/history": {
      "get": {
        "operationId": "get_v1_billing_history",
        "summary": "Your billing history, newest first: every credit you received, with what is left of it and when it expires, and every payment (invoices paid, payments that failed, refunds). `kind` is `all` (the default), `credits` or `payments`; `limit` is up to 100 (50 by default); pass `next_cursor` back as `cursor` for older entries. Owners only (with their own key).",
        "tags": [
          "Billing"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "kind",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BillingHistory"
                },
                "example": {
                  "entries": [
                    {
                      "at": "2026-10-01T01:00:12.000Z",
                      "credit": null,
                      "payment": {
                        "amount_usd": 54.12,
                        "invoice_number": "7F3A9C2E-0002",
                        "invoice_url": "https://invoice.example.com/i/7F3A9C2E-0002",
                        "kind": "invoice_paid",
                        "method": null,
                        "plan": "Pro",
                        "status": "paid"
                      }
                    },
                    {
                      "at": "2026-09-12T10:04:00.000Z",
                      "credit": {
                        "expires_at": "2026-10-12T10:04:00.000Z",
                        "granted_at": "2026-09-12T10:04:00.000Z",
                        "granted_usd": 40,
                        "kind": "card_bonus",
                        "remaining_usd": 34.24,
                        "status": "active"
                      },
                      "payment": null
                    },
                    {
                      "at": "2026-09-12T10:03:30.000Z",
                      "credit": null,
                      "payment": {
                        "amount_usd": 1,
                        "invoice_number": null,
                        "invoice_url": null,
                        "kind": "method_check",
                        "method": "Apple Pay",
                        "plan": null,
                        "status": "confirmed"
                      }
                    },
                    {
                      "at": "2026-09-04T01:00:09.000Z",
                      "credit": null,
                      "payment": {
                        "amount_usd": 50,
                        "invoice_number": "7F3A9C2E-0001",
                        "invoice_url": null,
                        "kind": "payment_failed",
                        "method": null,
                        "plan": null,
                        "status": "paid"
                      }
                    },
                    {
                      "at": "2026-09-02T08:00:00.000Z",
                      "credit": {
                        "expires_at": null,
                        "granted_at": "2026-09-02T08:00:00.000Z",
                        "granted_usd": 60,
                        "kind": "from_promigence",
                        "remaining_usd": 60,
                        "status": "active"
                      },
                      "payment": null
                    }
                  ],
                  "next_cursor": "MjAyNi0wOS0wMlQwODowMDowMC4wMDBaH2M6bGVkXzAx"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key"
      }
    },
    "/v1/billing/portal": {
      "post": {
        "operationId": "post_v1_billing_portal",
        "summary": "A link to the billing portal. Owners only (with their own key).",
        "tags": [
          "Billing"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PortalSession"
                },
                "example": {
                  "url": "https://billing.example/p/session/live_a1b2"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key"
      }
    },
    "/v1/captures/{id}": {
      "delete": {
        "operationId": "delete_v1_captures_id",
        "summary": "Destroy a preserved failure now. The bytes are deleted before the answer says so.",
        "tags": [
          "Runs"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaptureDeleted"
                },
                "example": {
                  "bytes": 812777472,
                  "deleted": true,
                  "deleted_at": "2026-09-20T09:14:39Z",
                  "ok": true,
                  "snapshot_id": "snap_cap_0a1b2c"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key"
      }
    },
    "/v1/credits/claim": {
      "post": {
        "operationId": "post_v1_credits_claim",
        "summary": "The claim the page sends: the link's token, the accepted terms version and the page's browser check. Answers the credit as it now stands: claimed, being checked (usually under 24 hours), or why there is none. Rate limited per address.",
        "tags": [
          "Billing"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreditOffer"
                },
                "example": {
                  "card_bonus_usd": 40,
                  "credit_usd": 10,
                  "expires_at": "2026-11-01T00:00:00.000Z",
                  "message": "You have $10 of free credit waiting. Claim it in your browser: `promigence credits claim`.",
                  "method_check_usd": 1,
                  "state": "claimable"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "413": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "none",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreditClaim"
              },
              "example": {
                "accept_terms": true,
                "terms_version": "2026-09-29",
                "token": "clm_example"
              }
            }
          }
        }
      }
    },
    "/v1/credits/claim-link": {
      "post": {
        "operationId": "post_v1_credits_claim_link",
        "summary": "A single-use link (15 minutes) to the page where the free credit is claimed (`promigence credits claim` opens it). A service key cannot ask for one. `409` with the reason when there is nothing to claim.",
        "tags": [
          "Billing"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ClaimLink"
                },
                "example": {
                  "expires_at": "2026-10-02T10:15:00.000Z",
                  "url": "https://api.promigence.ai/v1/auth/claim?t=3f9a…"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key"
      }
    },
    "/v1/credits/offer": {
      "get": {
        "operationId": "get_v1_credits_offer",
        "summary": "Your account's free credit: claimable (and how much, until when), claimed, being checked, needs a card, or none. The credit is claimed in a browser, never with an API call alone.",
        "tags": [
          "Billing"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreditOffer"
                },
                "example": {
                  "card_bonus_usd": 40,
                  "credit_usd": 10,
                  "expires_at": "2026-11-01T00:00:00.000Z",
                  "message": "You have $10 of free credit waiting. Claim it in your browser: `promigence credits claim`.",
                  "method_check_usd": 1,
                  "state": "claimable"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key"
      }
    },
    "/v1/execs/{id}": {
      "get": {
        "operationId": "get_v1_execs_id",
        "summary": "One exec by id alone, without knowing its sandbox or run. An exec belonging to another org is a 404, never a 403. A background command's id (`x_…`) answers as `GET /v1/sandboxes/:id/execs/:exec_id` does, with the same `?stream`, `?offset`, `?len` and `?wait_ms`; after a restart of the service that id is found only through its sandbox.",
        "tags": [
          "Execs"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "len",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0
            }
          },
          {
            "name": "stream",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "until",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "wait_ms",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExecView"
                },
                "example": {
                  "argv": [
                    "bash",
                    "-lc",
                    "pnpm test"
                  ],
                  "cpu_ms": 1180,
                  "cwd": "/workspace",
                  "env_keys": [
                    "CI"
                  ],
                  "exec_id": "exec_5d21a0",
                  "exit_code": 0,
                  "max_rss_kib": 262144,
                  "run_id": "run_4b91de",
                  "sandbox_id": "sbx_8f2c1a",
                  "signal": null,
                  "started_at": "2026-09-19T09:14:03Z",
                  "stderr": "",
                  "stdout": "ok\n",
                  "terminal": true,
                  "truncated": false,
                  "wall_ms": 1402
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              },
              "Promigence-Waited-Ms": {
                "$ref": "#/components/headers/Promigence-Waited-Ms"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key"
      }
    },
    "/v1/health": {
      "get": {
        "operationId": "get_v1_health",
        "summary": "Liveness, and whether the service can start sandboxes. The cheapest call there is; use it as a readiness check.",
        "tags": [
          "Meta"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Health"
                },
                "example": {
                  "build_sha": "",
                  "location": "US East Coast",
                  "ok": true,
                  "ready": true,
                  "serving": true,
                  "version": "0.0.1"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "none"
      }
    },
    "/v1/images/resolve": {
      "post": {
        "operationId": "post_v1_images_resolve",
        "summary": "Turn an image tag into a digest. `python:3.12` comes back as `python@sha256:…`, ready for `POST /v1/snapshots`, and you need no container tooling installed to ask. A reference that is already pinned is answered without contacting the registry. For a tag that names several architectures the answer pins what a pull of that tag would fetch and reports the `linux/amd64` build beside it; a tag with no `linux/amd64` build is refused here rather than at build time. `registry_secret` names a stored secret holding `user:password` for a private registry.",
        "tags": [
          "Snapshots"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ImageResolved"
                },
                "example": {
                  "already_pinned": false,
                  "digest": "sha256:8f0c6b1d5e2a7c9b4d3e1f0a6b5c4d3e2f1a0b9c8d7e6f5a4b3c2d1e0f9a8b7c6",
                  "image": "python@sha256:8f0c6b1d5e2a7c9b4d3e1f0a6b5c4d3e2f1a0b9c8d7e6f5a4b3c2d1e0f9a8b7c6",
                  "media_type": "application/vnd.oci.image.index.v1+json",
                  "ms": 412.3,
                  "ok": true,
                  "platform": "linux/amd64",
                  "platform_digest": "sha256:1a2b3c4d5e6f708192a3b4c5d6e7f8091a2b3c4d5e6f708192a3b4c5d6e7f809",
                  "platforms": [
                    "linux/amd64",
                    "linux/arm64"
                  ],
                  "registry": "registry-1.docker.io",
                  "registry_secret": null,
                  "repository": "library/python",
                  "tag": "3.12"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "413": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ImageResolve"
              },
              "example": {
                "image": "alpine:3.20"
              }
            }
          }
        }
      }
    },
    "/v1/integrations/github": {
      "get": {
        "operationId": "get_v1_integrations_github",
        "summary": "Your organization's GitHub connections, the ones still being finished, and the snapshots that follow a branch. `configured: false` when GitHub connections are not available.",
        "tags": [
          "GitHub"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GithubStatus"
                },
                "example": {
                  "app_slug": "promigence",
                  "configured": true,
                  "connections": [
                    {
                      "account": "acme",
                      "account_type": "Organization",
                      "connected_at": "2026-10-03T09:14:02.000Z",
                      "installation_id": 81234567,
                      "manage_url": "https://github.com/organizations/acme/settings/installations/81234567",
                      "repository_selection": "selected",
                      "suspended": false
                    }
                  ],
                  "pending": [
                    {
                      "account": "octo-dev",
                      "claimed_at": "2026-10-03T09:14:02.000Z",
                      "installation_id": 81234568,
                      "message": "GitHub has not confirmed this install yet; it usually does within seconds.",
                      "state": "waiting_for_github"
                    }
                  ],
                  "tracks": [
                    {
                      "alias": "api-main",
                      "branch": "main",
                      "built_sha": "4b825dc642cb6eb9a060e54bf8d69288fbee4904",
                      "created_at": "2026-10-03T09:14:02.000Z",
                      "head_sha": "4b825dc642cb6eb9a060e54bf8d69288fbee4904",
                      "repo": "acme/api",
                      "snapshot_id": "snap_live00000000000000000042",
                      "track_id": "trk_5f1c2a9e0b7d"
                    }
                  ]
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key"
      }
    },
    "/v1/integrations/github/connect": {
      "post": {
        "operationId": "post_v1_integrations_github_connect",
        "summary": "Start connecting a GitHub account: a link to install the platform's GitHub App on it, valid for 15 minutes. Open it in a browser, choose all repositories or selected ones, and GitHub sends you back; `GET /v1/integrations/github` then lists the connection. The App reads repository contents and metadata, nothing else. Body: `{}`.",
        "tags": [
          "GitHub"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GithubConnect"
                },
                "example": {
                  "app_slug": "promigence",
                  "expires_at": "2026-10-03T09:14:02.000Z",
                  "install_url": "https://github.com/apps/promigence/installations/new?state=eyJ…"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key"
      }
    },
    "/v1/integrations/github/installations/{installation_id}": {
      "delete": {
        "operationId": "delete_v1_integrations_github_installations_installation_id",
        "summary": "Disconnect a GitHub account: nothing is built from it any more and the snapshots that followed its branches stop following them. The App stays installed on GitHub until you uninstall it there (`uninstall_url`).",
        "tags": [
          "GitHub"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "installation_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GithubDisconnected"
                },
                "example": {
                  "account": "acme",
                  "disconnected": true,
                  "installation_id": 81234567,
                  "message": "acme is disconnected; the App stays installed on GitHub until you uninstall it there.",
                  "tracks_removed": 1,
                  "uninstall_url": "https://github.com/organizations/acme/settings/installations/81234567"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key"
      }
    },
    "/v1/integrations/github/repos": {
      "get": {
        "operationId": "get_v1_integrations_github_repos",
        "summary": "The repositories your GitHub connections can read, one page at a time (`page`, `per_page` up to 100). `full_name` is what `POST /v1/snapshots` takes as `repo: \"github:<full_name>\"`.",
        "tags": [
          "GitHub"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "per_page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GithubRepos"
                },
                "example": {
                  "has_more": false,
                  "page": 1,
                  "per_page": 100,
                  "repos": [
                    {
                      "account": "acme",
                      "archived": false,
                      "default_branch": "main",
                      "full_name": "acme/api",
                      "installation_id": 81234567,
                      "private": true,
                      "pushed_at": "2026-10-02T21:40:11Z"
                    }
                  ],
                  "total": 1
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key"
      }
    },
    "/v1/integrations/github/requests": {
      "post": {
        "operationId": "post_v1_integrations_github_requests",
        "summary": "Start connecting a GitHub account in the console, for yourself: a one-time ticket (5 minutes) and the console page that uses it (`connect_url`). Open the page in a browser signed in to the console as you, an owner of this organization; it takes you to GitHub, and `GET /v1/integrations/github/requests/{request_id}` then says how it ended. The page starts nothing for anyone else: opened while signed in to another account, the request ends as `wrong_user`. Owners only, like `connect`. `404` where the console cannot start it for this key (no console here, or a key with no person behind it): use `POST /v1/integrations/github/connect`. Body: `{}`.",
        "tags": [
          "GitHub"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConnectTicket"
                },
                "example": {
                  "connect_url": "https://console.promigence.ai/connect/sources/github?connect=1&ticket=ict_5b0e2c7d9a4f41e8b3c6d2a1f0e9c8b7",
                  "expires_at": "2026-10-03T09:14:02.000Z",
                  "request_id": "icr_3f9a51f07c2e4b183f9a51f07c2e4b18",
                  "ticket_id": "ict_5b0e2c7d9a4f41e8b3c6d2a1f0e9c8b7"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key",
        "x-promigence-status": 201
      }
    },
    "/v1/integrations/github/requests/{request_id}": {
      "get": {
        "operationId": "get_v1_integrations_github_requests_request_id",
        "summary": "How a GitHub connection request you started ended: `pending`, then `connected`, `updated` (already connected; its repository access changed), `pending_provider_approval` (an owner of the account must approve it on GitHub first), `declined`, `other_org`, `needs_admin`, `not_installer`, `wrong_user`, `expired` or `failed`, with a sentence that says what happened and what to do next. Only the person who started it reads it; anyone else gets `404`.",
        "tags": [
          "GitHub"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "request_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConnectRequest"
                },
                "example": {
                  "account": "acme",
                  "created_at": "2026-10-03T09:14:02.000Z",
                  "finished_at": "2026-10-03T09:14:02.000Z",
                  "message": "acme is connected to your Promigence organization.",
                  "provider": "github",
                  "request_id": "icr_3f9a51f07c2e4b183f9a51f07c2e4b18",
                  "state": "connected"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key"
      }
    },
    "/v1/integrations/github/tracks/{track_id}": {
      "delete": {
        "operationId": "delete_v1_integrations_github_tracks_track_id",
        "summary": "Stop a snapshot following its branch. The snapshot stays; pushes no longer build it.",
        "tags": [
          "GitHub"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "track_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GithubUntracked"
                },
                "example": {
                  "alias": "api-main",
                  "branch": "main",
                  "repo": "acme/api",
                  "track_id": "trk_5f1c2a9e0b7d",
                  "untracked": true
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key"
      }
    },
    "/v1/integrations/gitlab": {
      "get": {
        "operationId": "get_v1_integrations_gitlab",
        "summary": "Your organization's GitLab connections (each with the URL and token of an optional project webhook that makes tracked branches build at once), the ones waiting for an owner to confirm, and the snapshots that follow a branch. `configured: false` on a deployment with no GitLab application.",
        "tags": [
          "GitLab"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "claim",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "code",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "error",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "state",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GitlabStatus"
                },
                "example": {
                  "configured": true,
                  "connections": [
                    {
                      "broken": false,
                      "connected_at": "2026-10-04T09:14:02.000Z",
                      "connection_id": "glc_3d9a51f07c2e4b18",
                      "gitlab_url": "https://gitlab.com",
                      "user_id": 4811207,
                      "username": "octo-dev",
                      "webhook_token": "9f2c…",
                      "webhook_url": "https://api.promigence.ai/v1/integrations/gitlab/webhook/glc_3d9a51f07c2e4b18"
                    }
                  ],
                  "gitlab_url": "https://gitlab.com",
                  "pending": [
                    {
                      "authorized_at": "2026-10-04T09:14:02.000Z",
                      "connection_id": "glc_0a7b11c2d3e4f506",
                      "expires_at": "2026-10-04T09:29:02.000Z",
                      "message": "Waiting for an owner of the organization to confirm it in the browser that authorized it.",
                      "username": "octo-dev"
                    }
                  ],
                  "tracks": [
                    {
                      "alias": "api-main",
                      "branch": "main",
                      "built_sha": "4b825dc642cb6eb9a060e54bf8d69288fbee4904",
                      "created_at": "2026-10-04T09:14:02.000Z",
                      "head_sha": "4b825dc642cb6eb9a060e54bf8d69288fbee4904",
                      "repo": "acme/platform/api",
                      "snapshot_id": "snap_live00000000000000000043",
                      "track_id": "trk_9a1c2a9e0b7d"
                    }
                  ]
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key"
      }
    },
    "/v1/integrations/gitlab/connect": {
      "post": {
        "operationId": "post_v1_integrations_gitlab_connect",
        "summary": "Start connecting a GitLab user: a link to authorize the platform's GitLab application, read-only (`read_api read_repository`), valid for 15 minutes. Open it in a browser and authorize; then an owner of your organization confirms it, signed in to Promigence in that same browser. `GET /v1/integrations/gitlab` then lists the connection. Body: `{}`.",
        "tags": [
          "GitLab"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "claim",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "code",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "error",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "state",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GitlabConnect"
                },
                "example": {
                  "authorize_url": "https://gitlab.com/oauth/authorize?client_id=…&state=eyJ…",
                  "expires_at": "2026-10-04T09:14:02.000Z",
                  "gitlab_url": "https://gitlab.com",
                  "scopes": [
                    "read_api",
                    "read_repository"
                  ]
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key"
      }
    },
    "/v1/integrations/gitlab/connections/{connection_id}": {
      "delete": {
        "operationId": "delete_v1_integrations_gitlab_connections_connection_id",
        "summary": "Disconnect a GitLab user: the authorization is revoked on GitLab, nothing is built from it any more and the snapshots that followed branches through it stop following them.",
        "tags": [
          "GitLab"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "connection_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GitlabDisconnected"
                },
                "example": {
                  "connection_id": "glc_3d9a51f07c2e4b18",
                  "disconnected": true,
                  "message": "octo-dev is disconnected and our token is revoked on GitLab.",
                  "revoked": true,
                  "tracks_removed": 1,
                  "username": "octo-dev"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key"
      }
    },
    "/v1/integrations/gitlab/repos": {
      "get": {
        "operationId": "get_v1_integrations_gitlab_repos",
        "summary": "The projects a GitLab connection can read (the oldest working one unless `connection_id` names another), one page at a time (`page`, `per_page` up to 100). `path` is what `POST /v1/snapshots` takes as `repo: \"gitlab:<path>\"`.",
        "tags": [
          "GitLab"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "claim",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "code",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "connection_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "error",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "per_page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "state",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GitlabRepos"
                },
                "example": {
                  "has_more": false,
                  "page": 1,
                  "per_page": 100,
                  "repos": [
                    {
                      "archived": false,
                      "connection_id": "glc_3d9a51f07c2e4b18",
                      "default_branch": "main",
                      "last_activity_at": "2026-10-03T21:40:11Z",
                      "path": "acme/platform/api",
                      "private": true,
                      "project_id": 51234567
                    }
                  ]
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key"
      }
    },
    "/v1/integrations/gitlab/requests": {
      "post": {
        "operationId": "post_v1_integrations_gitlab_requests",
        "summary": "Start connecting a GitLab user in the console, for yourself: a one-time ticket (5 minutes) and the console page that uses it (`connect_url`). Open the page in a browser signed in to the console as you, an owner of this organization; it takes you to GitLab, and `GET /v1/integrations/gitlab/requests/{request_id}` then says how it ended. The page starts nothing for anyone else: opened while signed in to another account, the request ends as `wrong_user`. Owners only, like `connect`. `404` where the console cannot start it for this key: use `POST /v1/integrations/gitlab/connect`. Body: `{}`.",
        "tags": [
          "GitLab"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConnectTicket"
                },
                "example": {
                  "connect_url": "https://console.promigence.ai/connect/sources/github?connect=1&ticket=ict_5b0e2c7d9a4f41e8b3c6d2a1f0e9c8b7",
                  "expires_at": "2026-10-03T09:14:02.000Z",
                  "request_id": "icr_3f9a51f07c2e4b183f9a51f07c2e4b18",
                  "ticket_id": "ict_5b0e2c7d9a4f41e8b3c6d2a1f0e9c8b7"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key",
        "x-promigence-status": 201
      }
    },
    "/v1/integrations/gitlab/requests/{request_id}": {
      "get": {
        "operationId": "get_v1_integrations_gitlab_requests_request_id",
        "summary": "How a GitLab connection request you started ended: `pending`, then `connected`, `already_connected`, `declined`, `wrong_user`, `expired` or `failed`, with a sentence that says what happened and what to do next. Only the person who started it reads it; anyone else gets `404`.",
        "tags": [
          "GitLab"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "request_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConnectRequest"
                },
                "example": {
                  "account": "acme",
                  "created_at": "2026-10-03T09:14:02.000Z",
                  "finished_at": "2026-10-03T09:14:02.000Z",
                  "message": "acme is connected to your Promigence organization.",
                  "provider": "github",
                  "request_id": "icr_3f9a51f07c2e4b183f9a51f07c2e4b18",
                  "state": "connected"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key"
      }
    },
    "/v1/integrations/gitlab/tracks/{track_id}": {
      "delete": {
        "operationId": "delete_v1_integrations_gitlab_tracks_track_id",
        "summary": "Stop a snapshot following its GitLab branch. The snapshot stays; new commits no longer build it.",
        "tags": [
          "GitLab"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "track_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GitlabUntracked"
                },
                "example": {
                  "alias": "api-main",
                  "branch": "main",
                  "repo": "acme/platform/api",
                  "track_id": "trk_9a1c2a9e0b7d",
                  "untracked": true
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key"
      }
    },
    "/v1/invites": {
      "get": {
        "operationId": "get_v1_invites",
        "summary": "Invites waiting for your verified email address, from any organization. Needs a sign-in.",
        "tags": [
          "Organisation"
        ],
        "security": [
          {
            "identityToken": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InviteList"
                },
                "example": {
                  "invites": [
                    {
                      "created_at": "2026-09-26T09:14:02Z",
                      "email": "teammate@example.com",
                      "invite_id": "inv_3e9f0c2a",
                      "invited_by": "dev@example.com",
                      "org_id": "org_5c1a90",
                      "org_name": "acme",
                      "role": "member"
                    }
                  ]
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "token"
      }
    },
    "/v1/invites/{invite_id}/accept": {
      "post": {
        "operationId": "post_v1_invites_invite_id_accept",
        "summary": "Accept an invite and join the organization. Needs a sign-in: the identity token's own verified email must be the invited address, and the member who sent it must still be an owner.",
        "tags": [
          "Organisation"
        ],
        "security": [
          {
            "identityToken": []
          }
        ],
        "parameters": [
          {
            "name": "invite_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrgView"
                },
                "example": {
                  "card_on_file": true,
                  "created_at": "2026-09-18T11:02:44Z",
                  "default": true,
                  "members": 3,
                  "name": "acme",
                  "org_id": "org_5c1a90",
                  "projects": 2,
                  "role": "owner"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "token"
      }
    },
    "/v1/invites/{invite_id}/decline": {
      "post": {
        "operationId": "post_v1_invites_invite_id_decline",
        "summary": "Decline an invite sent to your verified email address. It is gone for good, and the organization may invite the address again.",
        "tags": [
          "Organisation"
        ],
        "security": [
          {
            "identityToken": []
          }
        ],
        "parameters": [
          {
            "name": "invite_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InviteRevoked"
                },
                "example": {
                  "invite_id": "inv_3e9f0c2a",
                  "revoked": true
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "token"
      }
    },
    "/v1/keys": {
      "get": {
        "operationId": "get_v1_keys",
        "summary": "List your org's keys: with an API key, its own project's; with an identity token, every project's. `?all=1` includes revoked ones.",
        "tags": [
          "Keys and sign-in"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "all",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/KeyList"
                },
                "example": {
                  "keys": [
                    {
                      "access": "full",
                      "created_at": "2026-09-18T11:02:44Z",
                      "created_by": "usr_71c0de",
                      "current": true,
                      "expires_at": null,
                      "key_id": "key_2f8a11",
                      "last_used_at": "2026-09-19T09:14:02Z",
                      "minted_by": null,
                      "name": "cli",
                      "prefix": "prom_api_9f3a1c0e",
                      "revoked_at": null
                    }
                  ],
                  "org_id": "org_5c1a90"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key"
      },
      "post": {
        "operationId": "post_v1_keys",
        "summary": "Mint a key. `api_key` is in the 201 response and is never retrievable again. A key minted by a key stays in that key's project, and is revoked when that key is; a service key cannot mint. A key does not expire unless you give it an expiry; past it, the key answers `401 key_expired`, and the org's owners are mailed 14 and 3 days before.",
        "tags": [
          "Keys and sign-in"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/KeyView"
                },
                "example": {
                  "access": "full",
                  "created_at": "2026-09-18T11:02:44Z",
                  "created_by": "usr_71c0de",
                  "current": true,
                  "expires_at": null,
                  "key_id": "key_2f8a11",
                  "last_used_at": "2026-09-19T09:14:02Z",
                  "minted_by": null,
                  "name": "cli",
                  "prefix": "prom_api_9f3a1c0e",
                  "revoked_at": null
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "413": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key",
        "x-promigence-status": 201,
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/KeyCreate"
              },
              "example": {
                "access": "run",
                "expires_in_days": 90,
                "name": "ci"
              }
            }
          }
        }
      }
    },
    "/v1/keys/{key_id}": {
      "delete": {
        "operationId": "delete_v1_keys_key_id",
        "summary": "Revoke a key, and every key it minted (and every key those minted): `also_revoked` lists them. Your own key is yours to revoke; another member's key, or any service key, needs the owner role; a service key may revoke only itself. `?reason=replaced` or `?reason=logout` from the key itself (the CLI rotating or ending its session key) revokes only that key.",
        "tags": [
          "Keys and sign-in"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "key_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "reason",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/KeyView"
                },
                "example": {
                  "access": "full",
                  "created_at": "2026-09-18T11:02:44Z",
                  "created_by": "usr_71c0de",
                  "current": true,
                  "expires_at": null,
                  "key_id": "key_2f8a11",
                  "last_used_at": "2026-09-19T09:14:02Z",
                  "minted_by": null,
                  "name": "cli",
                  "prefix": "prom_api_9f3a1c0e",
                  "revoked_at": null
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key"
      }
    },
    "/v1/llms.txt": {
      "get": {
        "operationId": "get_v1_llms_txt",
        "summary": "The agent guide as `text/plain` — the same document `promigence agent-guide` prints.",
        "tags": [
          "Meta"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "none"
      }
    },
    "/v1/me": {
      "get": {
        "operationId": "get_v1_me",
        "summary": "Who you are, what your limits are, what you have spent, and what trial credit is left.",
        "tags": [
          "Organisation"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Me"
                },
                "example": {
                  "card_on_file": false,
                  "concurrency": {
                    "in_use": 3,
                    "limit": 20
                  },
                  "default_spend_cap": 5,
                  "key": {
                    "key_id": "key_2f8a11",
                    "name": "cli",
                    "prefix": "prom_api_9f3a1c0e",
                    "service": false
                  },
                  "limits": {
                    "max_concurrency": 20,
                    "max_inflight": 20,
                    "max_sandbox_vcpus": 8,
                    "max_session_s": 3600
                  },
                  "location": "US East Coast",
                  "location_code": "us-east",
                  "notice": null,
                  "org": "acme",
                  "org_id": "org_5c1a90",
                  "plan": "hobby",
                  "spend": 5.76,
                  "spend_detail": {
                    "billable_seconds": 34286,
                    "by_kind": {
                      "build": 0.5,
                      "sandbox": 5.26
                    },
                    "currency": "usd",
                    "total": 5.76
                  },
                  "trial": {
                    "card_on_file": false,
                    "credits_available": 94.0888,
                    "credits_granted": 100,
                    "credits_remaining": 94.24,
                    "credits_reserved": 0.1512,
                    "egress_gb_cap": 20,
                    "egress_gb_used": 0.0195,
                    "egress_month": "2026-09",
                    "limits": {
                      "egress_gb_month": 20,
                      "max_concurrency": 20,
                      "max_sandbox_vcpus": 8,
                      "max_session_s": 3600,
                      "smtp": false
                    },
                    "on_trial": true,
                    "policy": {
                      "card_required_from": null,
                      "card_required_now": false,
                      "mode": "open",
                      "notice_from": null
                    }
                  },
                  "user": {
                    "created_at": "2026-09-18T11:02:44Z",
                    "email": "dev@example.com",
                    "email_verified": true,
                    "provider": "github",
                    "user_id": "usr_71c0de"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key"
      }
    },
    "/v1/me/ledger": {
      "get": {
        "operationId": "get_v1_me_ledger",
        "summary": "The rows behind `spend`: usage recorded while each sandbox runs and when it ends. With a project's key, that project's rows and the organization's credit grants; `spend` stays the organization's. `?limit=N`.",
        "tags": [
          "Organisation"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LedgerList"
                },
                "example": {
                  "entries": [
                    {
                      "amount": 0.006216,
                      "created_at": "2026-09-19T09:14:39Z",
                      "detail": "completed",
                      "entry_id": "led_0c3a91",
                      "episodes": 0,
                      "gib_second_usd": 0.0000045,
                      "interim": false,
                      "kind": "sandbox",
                      "mem_gib": 16,
                      "run_id": "run_4b91de",
                      "sandbox_id": "sbx_8f2c1a",
                      "seconds": 37,
                      "subject": "sbx_8f2c1a",
                      "tier": "standard",
                      "unit": 0.000168,
                      "vcpu_second_usd": 0.000014,
                      "vcpus": 8
                    }
                  ],
                  "next_cursor": null
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key"
      }
    },
    "/v1/me/outcomes": {
      "get": {
        "operationId": "get_v1_me_outcomes",
        "summary": "What the organization got this month, measured from its own runs and sandboxes: runs and sandboxes started, the median time to ready, failures on our side that were not billed and what was given back, hours paused and what they would have cost running, failed sandboxes kept to reopen, and for runs of two or more sandboxes how many times faster than one after another and the time not spent waiting. With a project's key, that project's. A figure with nothing behind it is `null`. `?period=month`.",
        "tags": [
          "Organisation"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "period",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Outcomes"
                },
                "example": {
                  "batch_runs": 160,
                  "batch_saved_s": 41160,
                  "batch_speedup": 41,
                  "failures_ours": 3,
                  "failures_ours_usd": 0.42,
                  "kept_failures": 38,
                  "paused_hours": 212,
                  "paused_usd": 97,
                  "period": "month",
                  "ready_ms_p50": 11.9,
                  "runs": 214,
                  "sandboxes": 1284,
                  "since": "2026-10-01T00:00:00.000Z"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key"
      }
    },
    "/v1/orgs": {
      "get": {
        "operationId": "get_v1_orgs",
        "summary": "The organizations you belong to, your role in each, and which one is your default. With an API key, only that key's own organization; a sign-in lists every one.",
        "tags": [
          "Organisation"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrgList"
                },
                "example": {
                  "orgs": [
                    {
                      "card_on_file": true,
                      "created_at": "2026-09-18T11:02:44Z",
                      "default": true,
                      "members": 3,
                      "name": "acme",
                      "org_id": "org_5c1a90",
                      "projects": 2,
                      "role": "owner"
                    }
                  ]
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key"
      },
      "post": {
        "operationId": "post_v1_orgs",
        "summary": "Create an organization. You become its owner and it starts with a `default` project. It gets no trial credit — the trial belongs to the person — so add a card before its first run.",
        "tags": [
          "Organisation"
        ],
        "security": [
          {
            "identityToken": []
          }
        ],
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrgView"
                },
                "example": {
                  "card_on_file": true,
                  "created_at": "2026-09-18T11:02:44Z",
                  "default": true,
                  "members": 3,
                  "name": "acme",
                  "org_id": "org_5c1a90",
                  "projects": 2,
                  "role": "owner"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "413": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "token",
        "x-promigence-status": 201,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/NameCreate"
              },
              "example": {
                "name": "acme-research"
              }
            }
          }
        }
      }
    },
    "/v1/orgs/{org}": {
      "delete": {
        "operationId": "delete_v1_orgs_org",
        "summary": "Delete an organization. Its keys stop working, pending invites are revoked and every member leaves it; a member for whom it was the only organization gets a fresh personal one (no trial credit). Owners only, signed in. Refused while it is suspended, has a subscription (cancel it in the billing portal first), a snapshot, a build running, a failure capture or a sandbox that has not ended (a paused one included). Its secrets are deleted, the commands and output of its runs and builds and the data stored for it are erased, and its name is freed; invoices, the billing ledger and the audit log are kept.",
        "tags": [
          "Organisation"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "org",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrgDeleted"
                },
                "example": {
                  "deleted": true,
                  "keys_revoked": 2,
                  "members_rehomed": 1,
                  "org_id": "org_2d77f0"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "413": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OrgDelete"
              },
              "example": {
                "confirm": "acme-research"
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "patch_v1_orgs_org",
        "summary": "Rename an organization. Owners only. Its id never changes; anything that names it by the old name (a script, `--org`, a saved URL) must use the new one. The same rules as a new name: free, and not starting with `promigence`.",
        "tags": [
          "Organisation"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "org",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrgView"
                },
                "example": {
                  "card_on_file": true,
                  "created_at": "2026-09-18T11:02:44Z",
                  "default": true,
                  "members": 3,
                  "name": "acme",
                  "org_id": "org_5c1a90",
                  "projects": 2,
                  "role": "owner"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "413": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OrgPatch"
              },
              "example": {
                "name": "acme-labs"
              }
            }
          }
        }
      }
    },
    "/v1/orgs/{org}/audit": {
      "get": {
        "operationId": "get_v1_orgs_org_audit",
        "summary": "The organization's audit log, newest first: keys minted and revoked, invites, role changes, removals, projects, billing events, suspension, and what support did to the organization (shown as `Promigence support`). Owners only, signed in. `?before=<seq>&limit=` (at most 100) pages back.",
        "tags": [
          "Organisation"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "org",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "before",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuditList"
                },
                "example": {
                  "entries": [
                    {
                      "action": "org.invite.create",
                      "actor": "dev@example.com",
                      "actor_type": "customer",
                      "at": "2026-09-27T08:02:11Z",
                      "ip": "203.0.113.7",
                      "outcome": "ok",
                      "seq": 41,
                      "target_id": "inv_3e9f0c2a",
                      "target_type": "invite"
                    }
                  ],
                  "org_id": "org_5c1a90"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key"
      }
    },
    "/v1/orgs/{org}/default": {
      "post": {
        "operationId": "post_v1_orgs_org_default",
        "summary": "Make this organization the one a sign-in and the CLI use when none is named.",
        "tags": [
          "Organisation"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "org",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrgView"
                },
                "example": {
                  "card_on_file": true,
                  "created_at": "2026-09-18T11:02:44Z",
                  "default": true,
                  "members": 3,
                  "name": "acme",
                  "org_id": "org_5c1a90",
                  "projects": 2,
                  "role": "owner"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key"
      }
    },
    "/v1/orgs/{org}/invites": {
      "get": {
        "operationId": "get_v1_orgs_org_invites",
        "summary": "Pending invites to an organization. An invite nobody accepts is gone after 14 days.",
        "tags": [
          "Organisation"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "org",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InviteList"
                },
                "example": {
                  "invites": [
                    {
                      "created_at": "2026-09-26T09:14:02Z",
                      "email": "teammate@example.com",
                      "invite_id": "inv_3e9f0c2a",
                      "invited_by": "dev@example.com",
                      "org_id": "org_5c1a90",
                      "org_name": "acme",
                      "role": "member"
                    }
                  ]
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key"
      },
      "post": {
        "operationId": "post_v1_orgs_org_invites",
        "summary": "Invite an email address. Owners only, signed in (not with a key). Only a signed-in user whose verified email is that address can accept it.",
        "tags": [
          "Organisation"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "org",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InviteView"
                },
                "example": {
                  "created_at": "2026-09-26T09:14:02Z",
                  "email": "teammate@example.com",
                  "invite_id": "inv_3e9f0c2a",
                  "invited_by": "dev@example.com",
                  "org_id": "org_5c1a90",
                  "org_name": "acme",
                  "role": "member"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "413": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key",
        "x-promigence-status": 201,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InviteCreate"
              },
              "example": {
                "email": "teammate@example.com"
              }
            }
          }
        }
      }
    },
    "/v1/orgs/{org}/invites/{invite_id}": {
      "delete": {
        "operationId": "delete_v1_orgs_org_invites_invite_id",
        "summary": "Revoke a pending invite. Owners only, signed in.",
        "tags": [
          "Organisation"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "org",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "invite_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InviteRevoked"
                },
                "example": {
                  "invite_id": "inv_3e9f0c2a",
                  "revoked": true
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key"
      }
    },
    "/v1/orgs/{org}/invites/{invite_id}/resend": {
      "post": {
        "operationId": "post_v1_orgs_org_invites_invite_id_resend",
        "summary": "Send a pending invite's email again: the same invite, its 14 days counted again from now. Owners only. At most once every 10 minutes and three times a day per invite.",
        "tags": [
          "Organisation"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "org",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "invite_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InviteView"
                },
                "example": {
                  "created_at": "2026-09-26T09:14:02Z",
                  "email": "teammate@example.com",
                  "invite_id": "inv_3e9f0c2a",
                  "invited_by": "dev@example.com",
                  "org_id": "org_5c1a90",
                  "org_name": "acme",
                  "role": "member"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key"
      }
    },
    "/v1/orgs/{org}/keys": {
      "post": {
        "operationId": "post_v1_orgs_org_keys",
        "summary": "Mint a key in an organization you belong to, in one of its projects. With an API key, only in that key's own organization; with a sign-in, in any of yours. `service: true` (owners only) makes a project's key that keeps working when the member who minted it leaves, and that cannot manage the organization; any other key is revoked with its minter's membership.",
        "tags": [
          "Keys and sign-in"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "org",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrgKeyView"
                },
                "example": {
                  "access": "run",
                  "api_key": "prom_api_9f3a1c0e…",
                  "created_at": "2026-09-26T09:22:40Z",
                  "created_by": "usr_71c0de",
                  "expires_at": "2027-01-31T00:00:00.000Z",
                  "key_id": "key_7d20c4aa",
                  "name": "ci",
                  "org_id": "org_5c1a90",
                  "prefix": "prom_api_9f3a1c0e",
                  "project_id": "prj_a41c09e2d7b3",
                  "service": true
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "413": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key",
        "x-promigence-status": 201,
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OrgKeyCreate"
              },
              "example": {
                "name": "ci",
                "service": true
              }
            }
          }
        }
      }
    },
    "/v1/orgs/{org}/members": {
      "get": {
        "operationId": "get_v1_orgs_org_members",
        "summary": "The members of an organization and their roles.",
        "tags": [
          "Organisation"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "org",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemberList"
                },
                "example": {
                  "members": [
                    {
                      "email": "dev@example.com",
                      "joined_at": "2026-09-18T11:02:44Z",
                      "role": "owner",
                      "user_id": "usr_71c0de",
                      "you": true
                    }
                  ],
                  "org_id": "org_5c1a90"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key"
      }
    },
    "/v1/orgs/{org}/members/{user_id}": {
      "delete": {
        "operationId": "delete_v1_orgs_org_members_user_id",
        "summary": "Remove a member (owners, signed in), or leave (your own user id, or `me`). The keys that person minted for themselves in the organization are revoked; service keys keep working. The last owner cannot leave, and nobody can leave their only organization; an owner removing someone from theirs gives them a fresh personal organization (no trial credit).",
        "tags": [
          "Organisation"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "org",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "user_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemberRemoved"
                },
                "example": {
                  "keys_revoked": 1,
                  "org_id": "org_5c1a90",
                  "removed": true,
                  "user_id": "usr_2b8e11"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key"
      },
      "patch": {
        "operationId": "patch_v1_orgs_org_members_user_id",
        "summary": "Change a member's role. Owners only, signed in (not with a key); an organization always keeps at least one owner.",
        "tags": [
          "Organisation"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "org",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "user_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemberList"
                },
                "example": {
                  "members": [
                    {
                      "email": "dev@example.com",
                      "joined_at": "2026-09-18T11:02:44Z",
                      "role": "owner",
                      "user_id": "usr_71c0de",
                      "you": true
                    }
                  ],
                  "org_id": "org_5c1a90"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "413": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MemberRoleSet"
              },
              "example": {
                "role": "owner"
              }
            }
          }
        }
      }
    },
    "/v1/orgs/{org}/projects": {
      "get": {
        "operationId": "get_v1_orgs_org_projects",
        "summary": "An organization's projects, each with what it was billed this calendar month (UTC): `month` and `month_spend_usd`, the figure its monthly cap is checked against. `?month=YYYY-MM` gives another month. API keys belong to a project; a project holds any number of repositories.",
        "tags": [
          "Organisation"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "org",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "month",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProjectList"
                },
                "example": {
                  "org_id": "org_5c1a90",
                  "projects": [
                    {
                      "created_at": "2026-09-26T09:20:11Z",
                      "default": false,
                      "keys": 2,
                      "month": "2026-10",
                      "month_spend_usd": 137.42,
                      "monthly_cap_usd": 500,
                      "name": "evals",
                      "org_id": "org_5c1a90",
                      "project_id": "prj_a41c09e2d7b3"
                    }
                  ]
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key"
      },
      "post": {
        "operationId": "post_v1_orgs_org_projects",
        "summary": "Create a project.",
        "tags": [
          "Organisation"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "org",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProjectView"
                },
                "example": {
                  "created_at": "2026-09-26T09:20:11Z",
                  "default": false,
                  "keys": 2,
                  "month": "2026-10",
                  "month_spend_usd": 137.42,
                  "monthly_cap_usd": 500,
                  "name": "evals",
                  "org_id": "org_5c1a90",
                  "project_id": "prj_a41c09e2d7b3"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "413": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key",
        "x-promigence-status": 201,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/NameCreate"
              },
              "example": {
                "name": "acme-research"
              }
            }
          }
        }
      }
    },
    "/v1/orgs/{org}/projects/{project}": {
      "delete": {
        "operationId": "delete_v1_orgs_org_projects_project",
        "summary": "Delete a project with no working keys, no snapshots, no builds running, no failure captures and no sandbox that has not ended. Its secrets go with it; its past runs move to the `default` project. Owners only, signed in; never the `default` project.",
        "tags": [
          "Organisation"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "org",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "project",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProjectDeleted"
                },
                "example": {
                  "deleted": true,
                  "project_id": "prj_a41c09e2d7b3"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key"
      },
      "patch": {
        "operationId": "patch_v1_orgs_org_projects_project",
        "summary": "Rename a project, set its monthly cap, or both. The `default` project keeps its name. The cap is the most the project may be billed in one calendar month (UTC) — its sandboxes, their data out and its builds — counting what its live sandboxes could still bill; a create, replay, open or extension past it is refused with `project_cap_reached` and nothing starts. Setting the cap is for owners, signed in (not with a key).",
        "tags": [
          "Organisation"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "org",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "project",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProjectView"
                },
                "example": {
                  "created_at": "2026-09-26T09:20:11Z",
                  "default": false,
                  "keys": 2,
                  "month": "2026-10",
                  "month_spend_usd": 137.42,
                  "monthly_cap_usd": 500,
                  "name": "evals",
                  "org_id": "org_5c1a90",
                  "project_id": "prj_a41c09e2d7b3"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "413": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ProjectPatch"
              },
              "example": {
                "monthly_cap_usd": 250
              }
            }
          }
        }
      }
    },
    "/v1/orgs/{org}/projects/{project}/move": {
      "post": {
        "operationId": "post_v1_orgs_org_projects_project_move",
        "summary": "Move a project to another organization: its snapshots and secrets go with it, its past runs stay with the organization that paid for them, in its default project, and every key of the project is revoked (mint new ones there). Owners of the source only, signed in; you must belong to the target, and the target must have a card on file. Refused for the `default` project, a name the target already uses, or while any of the project's sandboxes has not ended, a build is running or a failure capture is left.",
        "tags": [
          "Organisation"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "org",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "project",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProjectMoved"
                },
                "example": {
                  "from_org_id": "org_2d77f0",
                  "keys_revoked": 1,
                  "project_id": "prj_a41c09e2d7b3",
                  "secrets_moved": 2,
                  "snapshots_moved": 3,
                  "to_org_id": "org_5c1a90"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "413": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ProjectMove"
              },
              "example": {
                "to": "acme-prod"
              }
            }
          }
        }
      }
    },
    "/v1/pricing": {
      "get": {
        "operationId": "get_v1_pricing",
        "summary": "Your organization's price list, read live on every call from what billing charges: the per-second rates, every sandbox shape on sale and its price (a snapshot build is billed at its tier's), the limits, the free credit and the plan they come from (`scope: organization`). Needs an API key; without one the answer is `auth` (401). The published list prices are on the pricing page and in `promigence pricing` before you sign in. A run is billed at the rates in force when it was created.",
        "tags": [
          "Billing"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PricingView"
                },
                "example": {
                  "as_of": "2026-10-03T00:00:00.000Z",
                  "billing": "per_second",
                  "currency": "usd",
                  "free_credit": {
                    "card_bonus_usd": 40,
                    "expires_by": null,
                    "expiry_days_after_claim": 30,
                    "invite_required": false,
                    "signup_credit_usd": 10,
                    "terms_url": "https://www.promigence.ai/terms/credits/"
                  },
                  "granularity_seconds": 1,
                  "included_credits_usd": 0,
                  "limits": {
                    "build_max_s": 3600,
                    "default_timeout_s": 900,
                    "egress_gb_month": 20,
                    "max_concurrency": 20,
                    "max_count_per_run": 1000,
                    "max_egress_gb_month": 20,
                    "max_sandbox_vcpus": 8,
                    "max_session_s": 3600,
                    "smtp": false
                  },
                  "min_billable_seconds": 1,
                  "monthly_fee_usd": 0,
                  "monthly_minimum_usd": 0,
                  "org_id": "org_5c1a90",
                  "plan": {
                    "display_name": "Hobby",
                    "on_trial": true,
                    "plan_id": "hobby",
                    "version": null
                  },
                  "rates": {
                    "build_usd": 0.1656,
                    "egress_gb_usd": null,
                    "gib_second_usd": 0.0000045,
                    "preemptible_gib_second_usd": 0.00000225,
                    "preemptible_vcpu_second_usd": 0.000007,
                    "storage_gb_month_usd": null,
                    "vcpu_second_usd": 0.000014
                  },
                  "schema": "promigence.pricing/v1",
                  "scope": "organization",
                  "tiers": [
                    {
                      "available": true,
                      "disk_gib": 10,
                      "mem_gib": 1,
                      "name": "xsmall",
                      "per_hour_usd": 0.0666,
                      "per_second_usd": 0.0000185,
                      "preemptible_per_second_usd": 0.00000925,
                      "vcpus": 1
                    },
                    {
                      "available": true,
                      "disk_gib": 10,
                      "mem_gib": 4,
                      "name": "small",
                      "per_hour_usd": 0.1656,
                      "per_second_usd": 0.000046,
                      "preemptible_per_second_usd": 0.000023,
                      "vcpus": 2
                    },
                    {
                      "available": true,
                      "disk_gib": 20,
                      "mem_gib": 16,
                      "name": "medium",
                      "per_hour_usd": 0.4608,
                      "per_second_usd": 0.000128,
                      "preemptible_per_second_usd": 0.000064,
                      "vcpus": 4
                    },
                    {
                      "available": true,
                      "disk_gib": 40,
                      "mem_gib": 16,
                      "name": "large-16",
                      "per_hour_usd": 0.6624,
                      "per_second_usd": 0.000184,
                      "preemptible_per_second_usd": 0.000092,
                      "vcpus": 8
                    },
                    {
                      "available": true,
                      "disk_gib": 40,
                      "mem_gib": 32,
                      "name": "large",
                      "per_hour_usd": 0.9216,
                      "per_second_usd": 0.000256,
                      "preemptible_per_second_usd": 0.000128,
                      "vcpus": 8
                    },
                    {
                      "available": false,
                      "disk_gib": 80,
                      "mem_gib": 32,
                      "name": "xlarge",
                      "per_hour_usd": 1.3248,
                      "per_second_usd": 0.000368,
                      "preemptible_per_second_usd": 0.000184,
                      "vcpus": 16
                    },
                    {
                      "available": false,
                      "disk_gib": 160,
                      "mem_gib": 64,
                      "name": "2xlarge",
                      "per_hour_usd": 2.6496,
                      "per_second_usd": 0.000736,
                      "preemptible_per_second_usd": 0.000368,
                      "vcpus": 32
                    }
                  ]
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key"
      }
    },
    "/v1/referrals": {
      "get": {
        "operationId": "get_v1_referrals",
        "summary": "Your referral code and its offer (\"Give $X, get $Y\"), your referrals by status, what they earned you, the referral you came through, and your credit that expires. The code exists while an offer runs.",
        "tags": [
          "Billing"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReferralStatus"
                },
                "example": {
                  "code": "K7QM2XPD",
                  "earned_usd": 300,
                  "expiring_credits": [
                    {
                      "expires_at": "2026-11-02T09:00:00.000Z",
                      "granted_usd": 100,
                      "remaining_usd": 62.5
                    }
                  ],
                  "offer": {
                    "credit_expiry_days": 30,
                    "ends_at": null,
                    "get_usd": 100,
                    "give_usd": 50,
                    "headline": "Give $50, get $100",
                    "hold_days": 30,
                    "qualifying_plans": [
                      "pro"
                    ]
                  },
                  "program": "on",
                  "referrals": {
                    "held": 1,
                    "other": 1,
                    "pending": 2,
                    "rewarded": 3,
                    "under_review": 0
                  },
                  "referred_by": null
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key"
      }
    },
    "/v1/referrals/apply": {
      "post": {
        "operationId": "post_v1_referrals_apply",
        "summary": "Apply a referral code to your organization: before its first paid invoice and within the offer's window after the organization was created. The credit comes with your first paid plan invoice. Owners only (with their own key). Body: `{code}`.",
        "tags": [
          "Billing"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReferralApplied"
                },
                "example": {
                  "code": "K7QM2XPD",
                  "qualifying_plans": [
                    "pro"
                  ],
                  "reward_usd": 50,
                  "status": "pending"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "413": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReferralApply"
              },
              "example": {
                "code": "FRIEND-EXAMPLE"
              }
            }
          }
        }
      }
    },
    "/v1/runs": {
      "get": {
        "operationId": "get_v1_runs",
        "summary": "List your org's runs, newest first. Pages are `?limit=N` (1..=500, default 50) and `?cursor=`; echo back `next_cursor` and stop when it is `null`.",
        "tags": [
          "Runs"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RunList"
                },
                "example": {
                  "next_cursor": null,
                  "runs": [
                    {
                      "canceled": false,
                      "capture": "on_failure",
                      "count": 1,
                      "exec": null,
                      "finished_at": "2026-09-19T09:14:39Z",
                      "grade": null,
                      "labels": {
                        "suite": "nightly"
                      },
                      "network": "egress",
                      "quote": {
                        "gib_second_usd": 0.0000045,
                        "max_cost": 0.1512,
                        "mem_gib": 16,
                        "per_second_usd": 0.000168,
                        "seconds_per_sandbox": 900,
                        "vcpu_second_usd": 0.000014,
                        "vcpus": 8
                      },
                      "run_id": "run_4b91de",
                      "snapshot": "snap_c0ffee",
                      "snapshot_id": "snap_c0ffee",
                      "spend_cap": 5,
                      "started_at": "2026-09-19T09:14:02Z",
                      "state": "completed",
                      "tier": "standard",
                      "timeout_ms": 900000,
                      "verify_each": false
                    }
                  ]
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key"
      },
      "post": {
        "operationId": "post_v1_runs",
        "summary": "Fork N sandboxes from one snapshot, optionally running a command in each. Refused with 409 `cap_exceeded` before anything starts if the quote exceeds `spend_cap`. `?wait_ms=N` parks until the sandboxes are ready; honours `Idempotency-Key`.",
        "tags": [
          "Runs"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "wait_ms",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255,
              "pattern": "^[\\x21-\\x7E]+$"
            },
            "description": "Makes a retried create safe: send the same key on every attempt of ONE create and it starts, and bills, once. Kept 24 hours per org. The same key with the same request (method, path and JSON body) answers with the first answer — same status, same ids — marked `Idempotent-Replayed: true`. The same key with a different request is refused with 409 `idempotency_key_reused`. A repeat that arrives while the first is still running waits for its answer, or gets 409 `idempotency_key_in_use` with `Retry-After`. Only an answer that started something is kept: a create refused before anything started leaves the key free. The SDKs send one for every create they make."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RunCreated"
                },
                "example": {
                  "count": 1,
                  "idempotent_replay": false,
                  "launched": 1,
                  "preemptible": false,
                  "quote": {
                    "breakdown": [
                      {
                        "per_second_usd": 0.000168,
                        "sandbox_count": 1,
                        "seconds_per_sandbox": 900
                      }
                    ],
                    "gib_second_usd": 0.0000045,
                    "max_cost": 0.1512,
                    "mem_gib": 16,
                    "per_second_usd": 0.000168,
                    "seconds_per_sandbox": 900,
                    "vcpu_second_usd": 0.000014,
                    "vcpus": 8
                  },
                  "run_id": "run_4b91de",
                  "sandboxes": [
                    {
                      "committed_seconds": 900,
                      "eta_s": 90,
                      "one_time": true,
                      "queued_message": "making room for you, ready in about 2 min. Once that is done, the rest of this run starts at once.",
                      "queued_reason": "capacity_arriving",
                      "sandbox_id": "sbx_8f2c1a",
                      "state": "queued"
                    }
                  ],
                  "snapshot": "snap_c0ffee",
                  "snapshot_arg": "better-auth@main",
                  "snapshot_id": "snap_c0ffee",
                  "spend_cap": 5,
                  "state": "running",
                  "tier": "standard",
                  "timeout_ms": 900000,
                  "warnings": [
                    "1 of 1 queued: making room for you, ready in about 2 min. Once that is done, the rest of this run starts at once."
                  ]
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              },
              "Idempotent-Replayed": {
                "$ref": "#/components/headers/Idempotent-Replayed"
              },
              "Promigence-Waited-Ms": {
                "$ref": "#/components/headers/Promigence-Waited-Ms"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "413": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RunCreate"
              },
              "example": {
                "count": 10,
                "exec": {
                  "sh": "bun test"
                },
                "labels": {
                  "suite": "nightly"
                },
                "snapshot": "better-auth",
                "spend_cap": 5,
                "timeout_ms": 900000
              }
            }
          }
        }
      }
    },
    "/v1/runs/{id}": {
      "delete": {
        "operationId": "delete_v1_runs_id",
        "summary": "Cancel the queue and kill every live sandbox of the run.",
        "tags": [
          "Runs"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RunKilled"
                },
                "example": {
                  "killed": 2,
                  "ok": true,
                  "run_id": "run_4b91de"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key"
      },
      "get": {
        "operationId": "get_v1_runs_id",
        "summary": "One run and its sandboxes. `?wait_ms=N` long-polls until the run is finished, or every sandbox has ended or outlived its command (`kill_on_exit: false`, `command_outcome` set).",
        "tags": [
          "Runs"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "wait_ms",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RunView"
                },
                "example": {
                  "canceled": false,
                  "capacity": {
                    "awaiting_capacity": 0,
                    "blocked": null,
                    "eta_s": null,
                    "state": "ok"
                  },
                  "capture": "on_failure",
                  "count": 1,
                  "counts": {
                    "completed": 1
                  },
                  "exec": null,
                  "finished_at": "2026-09-19T09:14:39Z",
                  "grade": null,
                  "labels": {
                    "suite": "nightly"
                  },
                  "network": "egress",
                  "quote": {
                    "gib_second_usd": 0.0000045,
                    "max_cost": 0.1512,
                    "mem_gib": 16,
                    "per_second_usd": 0.000168,
                    "seconds_per_sandbox": 900,
                    "vcpu_second_usd": 0.000014,
                    "vcpus": 8
                  },
                  "run_id": "run_4b91de",
                  "sandboxes": [
                    {
                      "outcome": "completed",
                      "replay_of": null,
                      "sandbox_id": "sbx_8f2c1a",
                      "state": "ended"
                    }
                  ],
                  "snapshot": "snap_c0ffee",
                  "snapshot_id": "snap_c0ffee",
                  "spend_cap": 5,
                  "started_at": "2026-09-19T09:14:02Z",
                  "state": "completed",
                  "tier": "standard",
                  "timeout_ms": 900000,
                  "verify_each": false
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              },
              "Promigence-Waited-Ms": {
                "$ref": "#/components/headers/Promigence-Waited-Ms"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key"
      }
    },
    "/v1/runs/{id}/cancel": {
      "post": {
        "operationId": "post_v1_runs_id_cancel",
        "summary": "Stop what is still queued. Live sandboxes keep running — use `DELETE /v1/runs/:id` for those.",
        "tags": [
          "Runs"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RunCanceled"
                },
                "example": {
                  "canceled": 3,
                  "ok": true,
                  "run_id": "run_4b91de"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key"
      }
    },
    "/v1/runs/{id}/captures": {
      "get": {
        "operationId": "get_v1_runs_id_captures",
        "summary": "What is preserved of this run's failures, and when each goes.",
        "tags": [
          "Runs"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaptureList"
                },
                "example": {
                  "captures": [
                    {
                      "available": true,
                      "bytes": 812777472,
                      "captured_at": "2026-09-19T09:14:39Z",
                      "code": "exit_nonzero",
                      "expires_at": "2026-09-26T09:14:39Z",
                      "outcome": "task_failed",
                      "run_id": "run_4b91de",
                      "sandbox_id": "sbx_8f2c1a",
                      "snapshot_id": "snap_cap_0a1b2c"
                    }
                  ],
                  "ok": true,
                  "run_id": "run_4b91de"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key"
      }
    },
    "/v1/runs/{id}/open": {
      "post": {
        "operationId": "post_v1_runs_id_open",
        "summary": "Reopen a preserved failure as a new, live sandbox — the state the sandbox was in when it broke, not a re-run from the start. It has its own id and its own billing clock, out of what is left of the run's cap.",
        "tags": [
          "Runs"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255,
              "pattern": "^[\\x21-\\x7E]+$"
            },
            "description": "Makes a retried create safe: send the same key on every attempt of ONE create and it starts, and bills, once. Kept 24 hours per org. The same key with the same request (method, path and JSON body) answers with the first answer — same status, same ids — marked `Idempotent-Replayed: true`. The same key with a different request is refused with 409 `idempotency_key_reused`. A repeat that arrives while the first is still running waits for its answer, or gets 409 `idempotency_key_in_use` with `Retry-After`. Only an answer that started something is kept: a create refused before anything started leaves the key free. The SDKs send one for every create they make."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RunOpened"
                },
                "example": {
                  "code": "exit_nonzero",
                  "committed_seconds": 900,
                  "detail": "sbx_b2d40f is a NEW sandbox forked from what sbx_8f2c1a left behind; it bills from now",
                  "expires_at": "2026-09-26T09:14:39Z",
                  "failed_at": "2026-09-19T09:14:39Z",
                  "max_cost": 0.1512,
                  "ok": true,
                  "opened_from": "sbx_8f2c1a",
                  "outcome": "task_failed",
                  "ready_ms": 318,
                  "run_id": "run_4b91de",
                  "sandbox_id": "sbx_b2d40f",
                  "snapshot_id": "snap_cap_0a1b2c",
                  "state": "ready",
                  "timeout_ms": 900000
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              },
              "Idempotent-Replayed": {
                "$ref": "#/components/headers/Idempotent-Replayed"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "413": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RunOpen"
              },
              "example": {
                "sandbox_id": "sbx_8f2c1a",
                "timeout_ms": 600000
              }
            }
          }
        }
      }
    },
    "/v1/runs/{id}/replay": {
      "post": {
        "operationId": "post_v1_runs_id_replay",
        "summary": "Re-fork the sandboxes whose outcome was an environment failure. Each replay is a new sandbox row with `replay_of` set, billed like any other sandbox; what the failed original is billed is in the run's report (`cost`), and a failure our side shows was ours is credited back.",
        "tags": [
          "Runs"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255,
              "pattern": "^[\\x21-\\x7E]+$"
            },
            "description": "Makes a retried create safe: send the same key on every attempt of ONE create and it starts, and bills, once. Kept 24 hours per org. The same key with the same request (method, path and JSON body) answers with the first answer — same status, same ids — marked `Idempotent-Replayed: true`. The same key with a different request is refused with 409 `idempotency_key_reused`. A repeat that arrives while the first is still running waits for its answer, or gets 409 `idempotency_key_in_use` with `Retry-After`. Only an answer that started something is kept: a create refused before anything started leaves the key free. The SDKs send one for every create they make."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RunReplayed"
                },
                "example": {
                  "ok": true,
                  "replayed": 1,
                  "run_id": "run_4b91de",
                  "sandboxes": [
                    {
                      "replay_of": "sbx_8f2c1a",
                      "sandbox_id": "sbx_b2d40f",
                      "state": "queued"
                    }
                  ]
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              },
              "Idempotent-Replayed": {
                "$ref": "#/components/headers/Idempotent-Replayed"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "413": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RunReplay"
              },
              "example": {
                "env": {
                  "API_TOKEN": "your-token"
                },
                "sandbox_ids": [
                  "sbx_8f2c1a"
                ]
              }
            }
          }
        }
      }
    },
    "/v1/runs/{id}/report": {
      "get": {
        "operationId": "get_v1_runs_id_report",
        "summary": "The validity report: every sandbox, its outcome, and whether the failure was the environment's or the task's. Run through your project's secret redactor before it is serialised.",
        "tags": [
          "Runs"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Run"
                },
                "example": {
                  "alias": "better-auth@main",
                  "cost": {
                    "billable_seconds": 37,
                    "cap_killed": false,
                    "charged": 0.006216,
                    "per_second_usd": 0.000168,
                    "quoted": 0.1512,
                    "unbilled": 0
                  },
                  "finished_at": "2026-09-19T09:14:39Z",
                  "fork": {
                    "final_success_pct": 100,
                    "first_attempt_success_pct": 100,
                    "n": 1,
                    "percentile_method": "ceil-rank",
                    "replay": {
                      "n": 0,
                      "success_pct": 0
                    },
                    "warm_retries": 0
                  },
                  "labels": {
                    "suite": "nightly"
                  },
                  "quote": {
                    "breakdown": [
                      {
                        "per_second_usd": 0.000168,
                        "sandbox_count": 1,
                        "seconds_per_sandbox": 900
                      }
                    ],
                    "gib_second_usd": 0.0000045,
                    "max_cost": 0.1512,
                    "mem_gib": 16,
                    "per_second_usd": 0.000168,
                    "seconds_per_sandbox": 900,
                    "vcpu_second_usd": 0.000014,
                    "vcpus": 8
                  },
                  "requested": {
                    "allow_partial": false,
                    "count": 1,
                    "network": "egress",
                    "secrets": [],
                    "timeout_ms": 900000,
                    "verify_each": false
                  },
                  "run_id": "run_4b91de",
                  "sandboxes": [
                    {
                      "attempt": 1,
                      "billable_seconds": 37,
                      "committed_seconds": 900,
                      "cost": 0.006216,
                      "e2e_ms": 1523,
                      "env_verified": true,
                      "execs": [],
                      "outcome": "completed",
                      "sandbox_id": "sbx_8f2c1a",
                      "state": "ended",
                      "t_end": "2026-09-19T09:14:39Z",
                      "t_handoff": "2026-09-19T09:14:02Z",
                      "used_seconds": 37,
                      "warnings": []
                    }
                  ],
                  "schema": "promigence.report/v1",
                  "snapshot_id": "snap_c0ffee",
                  "spend_cap": 5,
                  "started_at": "2026-09-19T09:14:02Z",
                  "state": "completed",
                  "totals": {
                    "aborted_by_client": 0,
                    "cap_killed": 0,
                    "completed": 1,
                    "env_failed": 0,
                    "env_verified": 1,
                    "evidence_missing": 0,
                    "expired": 0,
                    "grader_failed": 0,
                    "not_started": 0,
                    "preempted": 0,
                    "snapshot_failed": 0,
                    "stopped_by_support": 0,
                    "task_failed": 0
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key"
      }
    },
    "/v1/runs/{id}/sandboxes": {
      "get": {
        "operationId": "get_v1_runs_id_sandboxes",
        "summary": "Only the sandboxes of a run. `?wait_ms=N` long-polls until nothing is queued any more.",
        "tags": [
          "Runs"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "wait_ms",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RunSandboxes"
                },
                "example": {
                  "capacity": {
                    "awaiting_capacity": 0,
                    "blocked": null,
                    "eta_s": null,
                    "state": "ok"
                  },
                  "run_id": "run_4b91de",
                  "sandboxes": [
                    {
                      "attempt": 1,
                      "auto_pause_mode": "requests",
                      "auto_pause_s": 0,
                      "created_at": "2026-09-19T09:14:01.988Z",
                      "e2e_ms": 1523,
                      "egress": {
                        "bytes": 1048576,
                        "cut": false
                      },
                      "elapsed_ms": null,
                      "env_verified": true,
                      "failure": null,
                      "labels": {
                        "suite": "nightly"
                      },
                      "optimize_for": "start",
                      "optimize_for_applied": "start",
                      "outcome": "completed",
                      "queued_ms": 12,
                      "ready_ms": 249,
                      "replay_of": null,
                      "retried_by": null,
                      "retry_of": null,
                      "run_id": "run_4b91de",
                      "sandbox_id": "sbx_8f2c1a",
                      "snapshot_id": "snap_c0ffee",
                      "state": "ended",
                      "t_end": "2026-09-19T09:14:39Z",
                      "t_handoff": "2026-09-19T09:14:02Z",
                      "timeout_ms": 300000,
                      "verify_each_ms": null,
                      "warnings": []
                    }
                  ]
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              },
              "Promigence-Waited-Ms": {
                "$ref": "#/components/headers/Promigence-Waited-Ms"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key"
      }
    },
    "/v1/runs/quote": {
      "post": {
        "operationId": "post_v1_runs_quote",
        "summary": "Price a run without starting one. No side effects, nothing reserved. Matched ahead of `/v1/runs/:id`, so a run can never be named `quote`.",
        "tags": [
          "Runs"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RunQuoteView"
                },
                "example": {
                  "billing": "per_second",
                  "breakdown": [
                    {
                      "per_second_usd": 0.000168,
                      "sandbox_count": 1,
                      "seconds_per_sandbox": 900
                    }
                  ],
                  "count": 1,
                  "credits_available": 94.0888,
                  "egress": {
                    "cap_gb_month": null,
                    "gb_usd": 0.09,
                    "in_max_cost": false,
                    "included_gb_month": 20,
                    "remaining_free_gb": 19.9805,
                    "used_gb": 0.0195
                  },
                  "gib_second_usd": 0.0000045,
                  "granularity_seconds": 1,
                  "max_cost": 0.1512,
                  "mem_gib": 16,
                  "min_billable_seconds": 1,
                  "per_hour_usd": 0.6048,
                  "per_second_usd": 0.000168,
                  "preemptible": false,
                  "quote": {
                    "breakdown": [
                      {
                        "per_second_usd": 0.000168,
                        "sandbox_count": 1,
                        "seconds_per_sandbox": 900
                      }
                    ],
                    "gib_second_usd": 0.0000045,
                    "max_cost": 0.1512,
                    "mem_gib": 16,
                    "per_second_usd": 0.000168,
                    "seconds_per_sandbox": 900,
                    "vcpu_second_usd": 0.000014,
                    "vcpus": 8
                  },
                  "seconds_per_sandbox": 900,
                  "snapshot": "better-auth@main",
                  "snapshot_id": "snap_c0ffee",
                  "spend_cap": 5,
                  "tier": "standard",
                  "timeout_ms": 900000,
                  "vcpu_second_usd": 0.000014,
                  "vcpus": 8,
                  "warnings": []
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "413": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RunQuoteRequest"
              },
              "example": {
                "count": 10,
                "snapshot": "better-auth",
                "timeout_ms": 900000
              }
            }
          }
        }
      }
    },
    "/v1/sandboxes": {
      "get": {
        "operationId": "get_v1_sandboxes",
        "summary": "List your org's sandboxes, newest first. `?labels=k=v,k2=v2` returns only those whose run carries every label given, and `?state=running,ready` narrows by state: `queued` is every sandbox still waiting to start, `awaiting_capacity` only those a run answer reports as waiting for capacity. Both filters run on the server, so they find a match older than one page — which is how two copies of your service agree on one sandbox instead of each starting its own. Pages are `?limit=N` (1..=500, default 50) and `?cursor=`; echo back `next_cursor` to get the next page, and stop when it is `null`. A short page is not the end: a filter can empty a page that still has more behind it.",
        "tags": [
          "Sandboxes"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "labels",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0
            }
          },
          {
            "name": "state",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SandboxList"
                },
                "example": {
                  "labels": {
                    "suite": "nightly"
                  },
                  "limit": 50,
                  "next_cursor": null,
                  "sandboxes": [
                    {
                      "attempt": 1,
                      "auto_pause_mode": "requests",
                      "auto_pause_s": 0,
                      "created_at": "2026-09-19T09:14:01.988Z",
                      "e2e_ms": 1523,
                      "egress": {
                        "bytes": 1048576,
                        "cut": false
                      },
                      "elapsed_ms": null,
                      "env_verified": true,
                      "failure": null,
                      "labels": {
                        "suite": "nightly"
                      },
                      "optimize_for": "start",
                      "optimize_for_applied": "start",
                      "outcome": "completed",
                      "queued_ms": 12,
                      "ready_ms": 249,
                      "replay_of": null,
                      "retried_by": null,
                      "retry_of": null,
                      "run_id": "run_4b91de",
                      "sandbox_id": "sbx_8f2c1a",
                      "snapshot_id": "snap_c0ffee",
                      "state": "ended",
                      "t_end": "2026-09-19T09:14:39Z",
                      "t_handoff": "2026-09-19T09:14:02Z",
                      "timeout_ms": 300000,
                      "verify_each_ms": null,
                      "warnings": []
                    }
                  ],
                  "state": [
                    "ended"
                  ]
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key"
      }
    },
    "/v1/sandboxes/{id}": {
      "delete": {
        "operationId": "delete_v1_sandboxes_id",
        "summary": "Kill it now. The answer's `outcome` says how it ended: `aborted_by_client` for a sandbox that had started, billed for the seconds it used; `not_started` for one still queued, which is not billed; or, when its command had already returned, that command's own outcome. A sandbox that had already ended answers with the outcome it ended with and `already_ended: true`.",
        "tags": [
          "Sandboxes"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SandboxKilled"
                },
                "example": {
                  "already_ended": false,
                  "ok": true,
                  "outcome": "aborted_by_client",
                  "sandbox_id": "sbx_8f2c1a",
                  "state": "ended"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key"
      },
      "get": {
        "operationId": "get_v1_sandboxes_id",
        "summary": "One sandbox, with its execs. `auto_pause_s` and `auto_pause_mode` report the idle rule it is under — the values `PATCH` sets; `auto_pause_s` is 0 when it never pauses itself on idle. `optimize_for` is what the sandbox asked for; `optimize_for_applied` is what its latest start or resume actually got (null before the first). They can differ — the next resume asks again.",
        "tags": [
          "Sandboxes"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SandboxView"
                },
                "example": {
                  "attempt": 1,
                  "auto_pause_mode": "requests",
                  "auto_pause_s": 0,
                  "billable_seconds": 42,
                  "cost_usd": 0.001932,
                  "created_at": "2026-09-19T09:14:01.988Z",
                  "e2e_ms": 1523,
                  "egress": {
                    "bytes": 1048576,
                    "cut": false
                  },
                  "elapsed_ms": null,
                  "env_verified": true,
                  "execs": [
                    {
                      "argv": [
                        "bash",
                        "-lc",
                        "pnpm test"
                      ],
                      "cpu_ms": 1180,
                      "cwd": "/workspace",
                      "env_keys": [
                        "CI"
                      ],
                      "exec_id": "exec_5d21a0",
                      "exit_code": 0,
                      "max_rss_kib": 262144,
                      "run_id": "run_4b91de",
                      "sandbox_id": "sbx_8f2c1a",
                      "signal": null,
                      "started_at": "2026-09-19T09:14:03Z",
                      "stderr": "",
                      "stdout": "ok\n",
                      "terminal": true,
                      "truncated": false,
                      "wall_ms": 1402
                    }
                  ],
                  "failure": null,
                  "labels": {
                    "suite": "nightly"
                  },
                  "optimize_for": "start",
                  "optimize_for_applied": "start",
                  "outcome": "completed",
                  "queued_ms": 12,
                  "ready_ms": 249,
                  "replay_of": null,
                  "retried_by": null,
                  "retry_of": null,
                  "run_id": "run_4b91de",
                  "sandbox_id": "sbx_8f2c1a",
                  "snapshot_id": "snap_c0ffee",
                  "state": "ended",
                  "t_end": "2026-09-19T09:14:39Z",
                  "t_handoff": "2026-09-19T09:14:02Z",
                  "timeout_ms": 300000,
                  "verify_each_ms": null,
                  "warnings": []
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key"
      },
      "patch": {
        "operationId": "patch_v1_sandboxes_id",
        "summary": "Extend a live sandbox's total lifetime, and set when it parks itself. `timeout_ms` sets the total, not an offset from now; 409 `cap_exceeded` if the extra seconds do not fit the run's cap. `auto_pause_s` parks the sandbox once it has been idle that long — 0 turns it off, the minimum is 2, and a sandbox with a command, a background command, a terminal or an SSH session still open is never idle, so a long build or a dev server is safe. `auto_pause_mode` says what idle means: `requests` (the default) counts calls to the sandbox; `activity` also waits until, for the whole window, nothing inside has used CPU or sent or received a byte, and no network connection to the outside is open — for an agent that runs inside the sandbox on its own. Start such an agent in the background of a command that returns: it keeps running when the sandbox wakes. An agent still running as an open command keeps the sandbox awake in either mode, because a pause would end it. A sandbox parked by this rule wakes by itself on its next command or file call, and parked time is not billed. Any of the fields may be sent on its own.",
        "tags": [
          "Sandboxes"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SandboxPatched"
                },
                "example": {
                  "committed_seconds": 1800,
                  "cost": {
                    "added": 0.1512,
                    "ceiling": 5,
                    "charged": 0.0062,
                    "live_commitment": 0.1574,
                    "remaining": 4.8426
                  },
                  "ok": true,
                  "run_id": "run_4b91de",
                  "sandbox_id": "sbx_8f2c1a",
                  "timeout_ms": 1800000
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "413": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SandboxPatch"
              },
              "example": {
                "auto_pause_mode": "requests",
                "auto_pause_s": 300
              }
            }
          }
        }
      }
    },
    "/v1/sandboxes/{id}/execs": {
      "get": {
        "operationId": "get_v1_sandboxes_id_execs",
        "summary": "List this sandbox's background execs.",
        "tags": [
          "Execs"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BackgroundExecList"
                },
                "example": {
                  "execs": [
                    {
                      "argv": "npm run dev",
                      "background": true,
                      "exec_id": "x_0_1_1789320609123",
                      "exit": {
                        "cpu_ms": 1180,
                        "exit_code": 0,
                        "max_rss_kib": 262144,
                        "oom_killed": false,
                        "signal": null,
                        "truncated": false,
                        "wall_ms": 61402
                      },
                      "sandbox_id": "sbx_8f2c1a",
                      "started_unix_ns": 1789320609123000000,
                      "state": "exited",
                      "stderr_bytes": 0,
                      "stderr_total": 0,
                      "stdin_open": false,
                      "stdout_bytes": 2048,
                      "stdout_total": 2048,
                      "truncated": false
                    }
                  ],
                  "sandbox_id": "sbx_8f2c1a"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key"
      },
      "post": {
        "operationId": "post_v1_sandboxes_id_execs",
        "summary": "Run a command. Buffered by default; `Accept: text/event-stream` streams it; `background: true` returns 202 with a handle instead of waiting. A sandbox parked by its `auto_pause_s` rule is woken first; one paused with `POST …/pause` is not, and answers that it is paused. `max_output_bytes` (default 64 KiB) is per stream and at most 32 MiB; output past it is cut and the reply says `truncated: true`.",
        "tags": [
          "Execs"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255,
              "pattern": "^[\\x21-\\x7E]+$"
            },
            "description": "Optional. Makes a retried command safe: send the same key on every attempt of ONE command and it runs once. Kept 24 hours per org. The same key with the same request answers with the first answer (same `exec_id`), marked `Idempotent-Replayed: true`; the same key with a different request is refused with 409 `idempotency_key_reused`. Honoured on a buffered or background command; a streamed one (`Accept: text/event-stream`) refuses a key. At most 1 MiB of output is kept for a replay: a replay of a longer answer is cut and says so with `replay_truncated: true`. Nothing is kept unless you send a key; the SDKs send one only when you pass it.",
            "x-promigence-opt-in": true
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExecResult"
                },
                "example": {
                  "cpu_ms": 1180,
                  "exec_id": "exec_5d21a0",
                  "exit_code": 0,
                  "sandbox_id": "sbx_8f2c1a",
                  "signal": null,
                  "stderr": "",
                  "stdout": "ok\n",
                  "truncated": false,
                  "wall_ms": 1402
                }
              },
              "text/event-stream": {
                "schema": {
                  "type": "string",
                  "description": "Sent instead of the JSON answer when the request has `Accept: text/event-stream`: server-sent events, each an `event:` name and a `data:` line of JSON. `x-promigence-events` names every event and its data."
                },
                "x-promigence-events": {
                  "stdout": {
                    "description": "A chunk of the command's standard output, base64 in `data`, in order.",
                    "data": {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "string",
                          "contentEncoding": "base64",
                          "description": "The bytes, base64."
                        }
                      },
                      "required": [
                        "data"
                      ]
                    }
                  },
                  "stderr": {
                    "description": "A chunk of the command's standard error, as `stdout`.",
                    "data": {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "string",
                          "contentEncoding": "base64",
                          "description": "The bytes, base64."
                        }
                      },
                      "required": [
                        "data"
                      ]
                    }
                  },
                  "exit": {
                    "description": "The command ended: `exec_id`, `sandbox_id`, `exit_code`, `signal`, `wall_ms`, `cpu_ms`, `truncated`, `terminal`, and `timed_out`, `oom_killed` and `reason` when they apply. The last event of a stream that worked.",
                    "data": {
                      "type": "object",
                      "additionalProperties": true,
                      "x-promigence-body": "unspecified"
                    }
                  },
                  "error": {
                    "description": "The command could not run or the stream failed: an error body as in every error answer (`code`, `message`, `fix`, `category`, `retryable`, ...). The last event of a stream that failed.",
                    "data": {
                      "$ref": "#/components/schemas/ErrorBody"
                    }
                  },
                  "heartbeat": {
                    "description": "Sent while nothing else is, so a quiet stream is told apart from a lost one. No data to read.",
                    "data": {
                      "type": "object",
                      "additionalProperties": true
                    }
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              },
              "Idempotent-Replayed": {
                "$ref": "#/components/headers/Idempotent-Replayed"
              }
            }
          },
          "202": {
            "description": "Accepted",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BackgroundExec"
                },
                "example": {
                  "argv": "npm run dev",
                  "background": true,
                  "exec_id": "x_0_1_1789320609123",
                  "exit": {
                    "cpu_ms": 1180,
                    "exit_code": 0,
                    "max_rss_kib": 262144,
                    "oom_killed": false,
                    "signal": null,
                    "truncated": false,
                    "wall_ms": 61402
                  },
                  "sandbox_id": "sbx_8f2c1a",
                  "started_unix_ns": 1789320609123000000,
                  "state": "exited",
                  "stderr_bytes": 0,
                  "stderr_total": 0,
                  "stdin_open": false,
                  "stdout_bytes": 2048,
                  "stdout_total": 2048,
                  "truncated": false
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              },
              "Idempotent-Replayed": {
                "$ref": "#/components/headers/Idempotent-Replayed"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "413": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ExecCreate"
              },
              "example": {
                "argv": [
                  "bun",
                  "typecheck"
                ],
                "cwd": "/work/repo",
                "env": {
                  "CI": "1"
                },
                "secrets": [
                  "NPM_TOKEN"
                ],
                "timeout_ms": 600000
              }
            }
          }
        }
      }
    },
    "/v1/sandboxes/{id}/execs/{exec_id}": {
      "delete": {
        "operationId": "delete_v1_sandboxes_id_execs_exec_id",
        "summary": "SIGKILL the background exec and drop its handle and buffered output.",
        "tags": [
          "Execs"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "exec_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExecForgotten"
                },
                "example": {
                  "exec_id": "x_0_1_1789320609123",
                  "forgotten": true,
                  "ok": true,
                  "sandbox_id": "sbx_8f2c1a"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key"
      },
      "get": {
        "operationId": "get_v1_sandboxes_id_execs_exec_id",
        "summary": "Read a background exec. `?stream=stdout|stderr&offset=&len=` takes a byte range; `?wait_ms=N` parks until it exits.",
        "tags": [
          "Execs"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "exec_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "len",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0
            }
          },
          {
            "name": "stream",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "until",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "wait_ms",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BackgroundExec"
                },
                "example": {
                  "argv": "npm run dev",
                  "background": true,
                  "exec_id": "x_0_1_1789320609123",
                  "exit": {
                    "cpu_ms": 1180,
                    "exit_code": 0,
                    "max_rss_kib": 262144,
                    "oom_killed": false,
                    "signal": null,
                    "truncated": false,
                    "wall_ms": 61402
                  },
                  "sandbox_id": "sbx_8f2c1a",
                  "started_unix_ns": 1789320609123000000,
                  "state": "exited",
                  "stderr_bytes": 0,
                  "stderr_total": 0,
                  "stdin_open": false,
                  "stdout_bytes": 2048,
                  "stdout_total": 2048,
                  "truncated": false
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              },
              "Promigence-Waited-Ms": {
                "$ref": "#/components/headers/Promigence-Waited-Ms"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key"
      }
    },
    "/v1/sandboxes/{id}/execs/{exec_id}/signal": {
      "post": {
        "operationId": "post_v1_sandboxes_id_execs_exec_id_signal",
        "summary": "Signal a background exec.",
        "tags": [
          "Execs"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "exec_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExecSignalled"
                },
                "example": {
                  "delivered": true,
                  "exec_id": "x_0_1_1789320609123",
                  "ok": true,
                  "sandbox_id": "sbx_8f2c1a",
                  "signal": 15
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "413": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ExecSignal"
              },
              "example": {
                "signal": "SIGTERM"
              }
            }
          }
        }
      }
    },
    "/v1/sandboxes/{id}/execs/{exec_id}/stdin": {
      "post": {
        "operationId": "post_v1_sandboxes_id_execs_exec_id_stdin",
        "summary": "Write to a running command's standard input, and close it. `data` is base64 — stdin is bytes, and a JSON string cannot carry all of them. Send `data` and `eof` together for the common \"write this and close\". The command must have been started with `stdin: true`; a process already running on `/dev/null` cannot be handed an input later, so writing to one is an error rather than a write that goes nowhere.",
        "tags": [
          "Execs"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "exec_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StdinAck"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "413": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ExecStdin"
              },
              "example": {
                "data": "aGVsbG8K",
                "eof": true
              }
            }
          }
        }
      }
    },
    "/v1/sandboxes/{id}/files": {
      "delete": {
        "operationId": "delete_v1_sandboxes_id_files",
        "summary": "Delete a path. Idempotent: a missing path answers `existed: false`, not 404. `?recursive=1` for a tree.",
        "tags": [
          "Files"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "path",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "recursive",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FileDeleted"
                },
                "example": {
                  "deleted": true,
                  "existed": true,
                  "ok": true,
                  "path": "/workspace/out.json",
                  "sandbox_id": "sbx_8f2c1a"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key"
      },
      "get": {
        "operationId": "get_v1_sandboxes_id_files",
        "summary": "Stream a file out. `?path=`.",
        "tags": [
          "Files"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "path",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/octet-stream": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              },
              "X-Promigence-Path": {
                "$ref": "#/components/headers/X-Promigence-Path"
              },
              "X-Promigence-Size": {
                "$ref": "#/components/headers/X-Promigence-Size"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key"
      },
      "put": {
        "operationId": "put_v1_sandboxes_id_files",
        "summary": "Write a file in. `?path=`; the body is the bytes. `?mode=` (octal, e.g. `755`) sets the file's permission bits; without it a file that already exists keeps its mode, as a shell `>` or an editor's save does, and a new file is `644`. A directory on the path that does not exist is created first (`mkdir -p`, mode 755). Large files are chunked by the SDKs at 16 MiB. `&offset=N` writes at byte N instead of replacing the file, so an interrupted upload resumes: its error's evidence says how many bytes were `written`. A body over the request limit is refused 413.",
        "tags": [
          "Files"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "mode",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0
            }
          },
          {
            "name": "path",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FileWritten"
                },
                "example": {
                  "bytes": 1048576,
                  "chunks": 1,
                  "mode": "644",
                  "offset": 0,
                  "ok": true,
                  "path": "/work/data.csv",
                  "sandbox_id": "sbx_8f2c1a",
                  "stat": {
                    "is_dir": false,
                    "is_symlink": false,
                    "mode": "644",
                    "mtime_unix_ns": 1790000000000000000,
                    "path": "/work/data.csv",
                    "size": 1048576
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "413": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key",
        "requestBody": {
          "required": true,
          "content": {
            "application/octet-stream": {
              "schema": {
                "type": "string",
                "format": "binary"
              }
            }
          }
        }
      }
    },
    "/v1/sandboxes/{id}/files/archive": {
      "post": {
        "operationId": "post_v1_sandboxes_id_files_archive",
        "summary": "Pack a directory into a tar **inside the sandbox** and answer with where it landed and how big it is. Download it with the ordinary chunked file read. Splitting it this way is what lets a directory of any size come out: the transfer is the byte path you already have, not a second one with its own limit. `exclude` takes name globs like `.git`.",
        "tags": [
          "Files"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ArchiveInfo"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "413": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FileArchive"
              },
              "example": {
                "exclude": [
                  ".git"
                ],
                "out": "/tmp/repo.tar.gz",
                "path": "/work/repo"
              }
            }
          }
        }
      }
    },
    "/v1/sandboxes/{id}/files/chmod": {
      "post": {
        "operationId": "post_v1_sandboxes_id_files_chmod",
        "summary": "Change permissions and ownership. `mode` is a number or an octal string like `\"755\"`. Ownership is changed on the symlink itself, never on what it points at.",
        "tags": [
          "Files"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FileInfo"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "413": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FileChmod"
              },
              "example": {
                "mode": 493,
                "path": "/work/run.sh"
              }
            }
          }
        }
      }
    },
    "/v1/sandboxes/{id}/files/copy": {
      "post": {
        "operationId": "post_v1_sandboxes_id_files_copy",
        "summary": "Copy a file, or a whole tree with `recursive`. A symlink is copied as a symlink, never followed.",
        "tags": [
          "Files"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FileInfo"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "413": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FileCopy"
              },
              "example": {
                "from": "/work/a",
                "recursive": true,
                "to": "/work/a-copy"
              }
            }
          }
        }
      }
    },
    "/v1/sandboxes/{id}/files/extract": {
      "post": {
        "operationId": "post_v1_sandboxes_id_files_extract",
        "summary": "Unpack a tar that is already inside the sandbox. `strip` drops leading path components, like `tar --strip-components`. An entry that is absolute or contains `..` is refused.",
        "tags": [
          "Files"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExtractResult"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "413": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FileExtract"
              },
              "example": {
                "archive": "/tmp/repo.tar.gz",
                "into": "/work/restored",
                "strip": 1
              }
            }
          }
        }
      }
    },
    "/v1/sandboxes/{id}/files/list": {
      "get": {
        "operationId": "get_v1_sandboxes_id_files_list",
        "summary": "List a directory. `?path=`, plus `?recursive=1`, `?depth=N`, `?limit=N` and `?hidden=0`. Entries carry name, size, mode, uid, gid, mtime and kind. A listing cut short by `limit` says `truncated: true` rather than looking like the end of the directory.",
        "tags": [
          "Files"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "contains",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "hidden",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ignore_case",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0
            }
          },
          {
            "name": "path",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "pattern",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "recursive",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FileListing"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key"
      }
    },
    "/v1/sandboxes/{id}/files/mkdir": {
      "post": {
        "operationId": "post_v1_sandboxes_id_files_mkdir",
        "summary": "Create a directory. `parents` is `mkdir -p` and makes an existing directory a success; without it a missing parent is a 404 and an existing path is a conflict, which is what a caller using the call as a lock wants.",
        "tags": [
          "Files"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FileInfo"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "413": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FileMkdir"
              },
              "example": {
                "mode": "755",
                "parents": true,
                "path": "/work/out"
              }
            }
          }
        }
      }
    },
    "/v1/sandboxes/{id}/files/move": {
      "post": {
        "operationId": "post_v1_sandboxes_id_files_move",
        "summary": "Rename or move a path. Works across filesystems. Without `overwrite` an existing destination is a conflict rather than something silently destroyed.",
        "tags": [
          "Files"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FileInfo"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "413": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FileMove"
              },
              "example": {
                "from": "/work/a.txt",
                "overwrite": true,
                "to": "/work/b.txt"
              }
            }
          }
        }
      }
    },
    "/v1/sandboxes/{id}/files/search": {
      "get": {
        "operationId": "get_v1_sandboxes_id_files_search",
        "summary": "Find files under `?path=`. `?pattern=` is a glob over the file name (`*.py`); `?contains=` is literal text to find inside the files that match, which answers with the line number and the line. `?ignore_case=1`, `?limit=N`, `?hidden=0`. Binary files are skipped rather than printed.",
        "tags": [
          "Files"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "contains",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "hidden",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ignore_case",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0
            }
          },
          {
            "name": "path",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "pattern",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "recursive",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SearchResult"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key"
      }
    },
    "/v1/sandboxes/{id}/files/stat": {
      "get": {
        "operationId": "get_v1_sandboxes_id_files_stat",
        "summary": "Size, mode, mtime and kind for one path. `?path=`.",
        "tags": [
          "Files"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "path",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FileStatView"
                },
                "example": {
                  "path": "/workspace/out.json",
                  "sandbox_id": "sbx_8f2c1a",
                  "stat": {
                    "is_dir": false,
                    "is_symlink": false,
                    "mode": "644",
                    "mtime_unix_ns": 1789320609000000000,
                    "path": "/workspace/out.json",
                    "size": 4096
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key"
      }
    },
    "/v1/sandboxes/{id}/network": {
      "get": {
        "operationId": "get_v1_sandboxes_id_network",
        "summary": "Read the network policy a live sandbox is running under.",
        "tags": [
          "Sandboxes"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SandboxNetwork"
                },
                "example": {
                  "network": "egress",
                  "refused_connections": 0,
                  "refused_hosts": [],
                  "refused_lookups": 0,
                  "sandbox_id": "sbx_8f2c1a",
                  "state": "running",
                  "via_secret": [
                    {
                      "hosts": [
                        "api.openai.com"
                      ],
                      "secret": "OPENAI_API_KEY"
                    }
                  ]
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key"
      },
      "post": {
        "operationId": "post_v1_sandboxes_id_network",
        "summary": "Cut a live sandbox's egress. Use it to fetch dependencies first and close the network before the agent runs. One direction only: there is no call that opens egress again, so a sandbox can never widen its own access.",
        "tags": [
          "Sandboxes"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SandboxNetworkCut"
                },
                "example": {
                  "applied": true,
                  "network": {
                    "mode": "none"
                  },
                  "sandbox_id": "sbx_8f2c1a",
                  "state": "running"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "413": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SandboxNetworkSet"
              },
              "example": {
                "network": "none"
              }
            }
          }
        }
      }
    },
    "/v1/sandboxes/{id}/pause": {
      "post": {
        "operationId": "post_v1_sandboxes_id_pause",
        "summary": "Park the sandbox: it does not count against your concurrency limit, and paused time is not billed. Background commands started with `background: true` are ended by the pause, and the answer says how many (`background_execs_killed`, only when there were any); start them again after resume. A sandbox that was given the value of a secret pauses as usual, and the answer carries a `secrets_in_saved_state` warning.",
        "tags": [
          "Sandboxes"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SandboxPaused"
                },
                "example": {
                  "background_execs_killed": 1,
                  "bytes": {
                    "allocated": 812777472
                  },
                  "durable": true,
                  "ok": true,
                  "paused_id": "psd_5c0e9a41d2b7f3086e1a4c95",
                  "recorded": true,
                  "sandbox_id": "sbx_8f2c1a",
                  "state": "paused",
                  "took_ms": 431
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key"
      }
    },
    "/v1/sandboxes/{id}/ports": {
      "get": {
        "operationId": "get_v1_sandboxes_id_ports",
        "summary": "List this sandbox's preview URLs.",
        "tags": [
          "Ports and terminal"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PortList"
                },
                "example": {
                  "ports": [
                    {
                      "created_unix_ns": 1789320609000000000,
                      "host_url_label": "p_9f31c4e0",
                      "port": 3000,
                      "sandbox_id": "sbx_8f2c1a",
                      "token": "p_9f31c4e0",
                      "url": "https://p-9f31c4e0.preview.promigence.ai/"
                    }
                  ],
                  "sandbox_id": "sbx_8f2c1a"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key"
      },
      "post": {
        "operationId": "post_v1_sandboxes_id_ports",
        "summary": "Mint a preview URL for a port in the sandbox. Anyone holding the URL can reach the port — it is a bearer token in a link, so pass `ttl_s` to make it stop working on its own rather than relying on someone remembering to revoke it. `url` is the form to use; `path_url` and `host_url` are always returned by name, so a client that needs one specifically never has to parse `url`.",
        "tags": [
          "Ports and terminal"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Port"
                },
                "example": {
                  "created_unix_ns": 1789320609000000000,
                  "host_url_label": "p_9f31c4e0",
                  "port": 3000,
                  "sandbox_id": "sbx_8f2c1a",
                  "token": "p_9f31c4e0",
                  "url": "https://p-9f31c4e0.preview.promigence.ai/"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "413": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PortOpen"
              },
              "example": {
                "port": 3000
              }
            }
          }
        }
      }
    },
    "/v1/sandboxes/{id}/ports/{token_or_port}": {
      "delete": {
        "operationId": "delete_v1_sandboxes_id_ports_token_or_port",
        "summary": "Revoke one URL by its token, or every URL for a port by the port number.",
        "tags": [
          "Ports and terminal"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "token_or_port",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PortsRevoked"
                },
                "example": {
                  "ok": true,
                  "revoked": [
                    "p_9f31c4e0"
                  ],
                  "sandbox_id": "sbx_8f2c1a"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key"
      }
    },
    "/v1/sandboxes/{id}/probe": {
      "post": {
        "operationId": "post_v1_sandboxes_id_probe",
        "summary": "Re-check the sandbox's files against what the verified snapshot recorded. `first_bad_path` is the first path that differs.",
        "tags": [
          "Sandboxes"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SandboxProbe"
                },
                "example": {
                  "checked": "verified_paths",
                  "first_bad_path": null,
                  "ms": 18,
                  "ok": true,
                  "sandbox_id": "sbx_8f2c1a"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "413": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SandboxProbeRequest"
              },
              "example": {
                "paths": [
                  "/work/repo"
                ]
              }
            }
          }
        }
      }
    },
    "/v1/sandboxes/{id}/pty": {
      "get": {
        "operationId": "get_v1_sandboxes_id_pty",
        "summary": "A WebSocket terminal, relayed byte for byte. `?cols=&rows=&cmd=`. Authenticated by the `Authorization` header, never a query string. Its `open` event carries `resume`: send it back in the `promigence-resume` header (from a browser, as the subprotocol `promigence.resume.<resume>`), with `?received=` the output bytes you have, to pick the same terminal up where it left off after a dropped connection or a service update. If some of its output was not kept meanwhile, the `open` event's `dropped` says how many bytes. One that can no longer be picked up again answers 404.",
        "tags": [
          "Ports and terminal"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "cmd",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "cols",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0
            }
          },
          {
            "name": "received",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0
            }
          },
          {
            "name": "rows",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0
            }
          }
        ],
        "responses": {
          "101": {
            "description": "Switching Protocols. The socket then speaks websocket; there is no response body."
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key",
        "x-promigence-upgrade": "websocket"
      }
    },
    "/v1/sandboxes/{id}/resume": {
      "post": {
        "operationId": "post_v1_sandboxes_id_resume",
        "summary": "Bring a paused sandbox back where it was, and restart the billing clock.",
        "tags": [
          "Sandboxes"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SandboxResumed"
                },
                "example": {
                  "ok": true,
                  "paused_id": "psd_5c0e9a41d2b7f3086e1a4c95",
                  "recorded": true,
                  "sandbox_id": "sbx_8f2c1a",
                  "state": "ready",
                  "took_ms": 262
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "413": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SandboxResume"
              },
              "example": {
                "optimize_for": "start"
              }
            }
          }
        }
      }
    },
    "/v1/sandboxes/{id}/snapshot": {
      "post": {
        "operationId": "post_v1_sandboxes_id_snapshot",
        "summary": "Snapshot a running sandbox without stopping it, and get back an ordinary snapshot id you can fork. Background processes are ended first and the count is in the reply. The new snapshot inherits the tier and source of the snapshot this sandbox came from. It is not marked verified: the sandbox has run your code since, so verification has to be earned again rather than inherited. A sandbox that was given the value of a secret is refused with `secrets_in_snapshot` (409), because the snapshot, and every sandbox started from it, could contain that value; `force: true` takes it anyway and the answer carries a `secrets_in_saved_state` warning. An `alias` another snapshot already has is refused unless `move_alias: true` moves it here (the other snapshot stays, unnamed).",
        "tags": [
          "Sandboxes"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SandboxSnapshot"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "413": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SandboxSnapshotCreate"
              },
              "example": {
                "alias": "after-install"
              }
            }
          }
        }
      }
    },
    "/v1/sandboxes/{id}/ssh": {
      "get": {
        "operationId": "get_v1_sandboxes_id_ssh",
        "summary": "The keys this sandbox will accept over SSH, and for how long.",
        "tags": [
          "Ports and terminal"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SshAccessList"
                },
                "example": {
                  "host_key": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIExampleHostKeyBytesForTheDoc",
                  "host_key_fingerprint": "SHA256:9zYx8wVu7Ts6Rq5Pp4Oo3Nn2Mm1Ll0Kk9Jj8Ii7Hh6",
                  "idle_timeout_s": 900,
                  "keys": [
                    {
                      "created_at": "2026-09-19T09:14:02Z",
                      "expires_at": "2026-09-19T10:14:02Z",
                      "fingerprint": "SHA256:0aVX0hbJ9kQ2pR7uT1wYz3mN6sD8fG4hJ5kL7nP9qR0",
                      "key_id": "sk_4c1f9a2b",
                      "token_active": true,
                      "user": "sbx_8f2c1a"
                    }
                  ],
                  "sandbox_id": "sbx_8f2c1a"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key"
      },
      "post": {
        "operationId": "post_v1_sandboxes_id_ssh",
        "summary": "Authorise an `ssh-ed25519` public key for this sandbox and mint the short-lived credential an SSH connection to it uses. The login name is the sandbox id; the answer carries the sandbox's own host key, so a client can pin it instead of turning host verification off.",
        "tags": [
          "Ports and terminal"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SshAccess"
                },
                "example": {
                  "expires_at": "2026-09-19T10:14:02Z",
                  "fingerprint": "SHA256:0aVX0hbJ9kQ2pR7uT1wYz3mN6sD8fG4hJ5kL7nP9qR0",
                  "host": "sbx_8f2c1a.ssh.promigence.ai",
                  "host_key": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIExampleHostKeyBytesForTheDoc",
                  "host_key_fingerprint": "SHA256:9zYx8wVu7Ts6Rq5Pp4Oo3Nn2Mm1Ll0Kk9Jj8Ii7Hh6",
                  "idle_timeout_s": 900,
                  "key_id": "sk_4c1f9a2b",
                  "proxy_command": "promigence sandbox ssh sbx_8f2c1a --proxy",
                  "sandbox_id": "sbx_8f2c1a",
                  "ssh_command": "ssh -o ProxyCommand='promigence sandbox ssh sbx_8f2c1a --proxy' sbx_8f2c1a@sbx_8f2c1a.ssh.promigence.ai",
                  "token": "prom_ssh_0f1e2d3c4b5a69788796a5b4c3d2e1f0",
                  "user": "sbx_8f2c1a"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "413": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SshAccessRequest"
              },
              "example": {
                "public_key": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIExampleKeyBytesForTheDoc me@laptop",
                "ttl_s": 3600
              }
            }
          }
        }
      }
    },
    "/v1/sandboxes/{id}/ssh/{key_id}": {
      "delete": {
        "operationId": "delete_v1_sandboxes_id_ssh_key_id",
        "summary": "Revoke one key by id or fingerprint, and the access credential issued with it. Idempotent: `revoked: false` means neither existed.",
        "tags": [
          "Ports and terminal"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "key_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SshRevoked"
                },
                "example": {
                  "key_id": "sk_4c1f9a2b",
                  "revoked": true,
                  "sandbox_id": "sbx_8f2c1a"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key"
      }
    },
    "/v1/sandboxes/{id}/ssh/connect": {
      "get": {
        "operationId": "get_v1_sandboxes_id_ssh_connect",
        "summary": "A WebSocket carrying the SSH byte stream, relayed byte for byte. Accepts either an API key or the short-lived per-sandbox credential from `POST /v1/sandboxes/:id/ssh`, in the `Authorization` header. This is what `promigence sandbox ssh <id> --proxy` speaks; you do not call it by hand.",
        "tags": [
          "Ports and terminal"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "101": {
            "description": "Switching Protocols. The socket then speaks websocket; there is no response body."
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key",
        "x-promigence-upgrade": "websocket"
      }
    },
    "/v1/secrets": {
      "get": {
        "operationId": "get_v1_secrets",
        "summary": "The calling key's project's secret names and shapes, and for a bound secret its `urls` and `env` as `POST /v1/secrets` answers them. Never values.",
        "tags": [
          "Secrets"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SecretList"
                },
                "example": {
                  "secrets": [
                    {
                      "bytes": 51,
                      "created_at": "2026-09-19T09:14:02Z",
                      "env": {
                        "OPENAI_BASE_URL": "<the address promigence secrets set prints>/v1"
                      },
                      "headers": [
                        "api-key",
                        "authorization",
                        "x-api-key",
                        "x-goog-api-key"
                      ],
                      "hosts": [
                        "api.openai.com"
                      ],
                      "name": "OPENAI_API_KEY",
                      "raw": "allowed",
                      "scan_responses": true,
                      "updated_at": "2026-09-19T09:14:02Z",
                      "urls": [
                        "<the address promigence secrets set prints>"
                      ]
                    },
                    {
                      "bytes": 37,
                      "created_at": "2026-09-19T09:14:02Z",
                      "name": "HF_TOKEN",
                      "updated_at": "2026-09-19T09:14:02Z"
                    }
                  ]
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key"
      },
      "post": {
        "operationId": "post_v1_secrets",
        "summary": "Store a secret in the calling key's project (the same name may hold a different value in another project). Write-only: no route ever returns a value, and only that project's sandboxes are given it. With `hosts` the secret is bound to those hosts: requests a sandbox sends to the address in the answer's `urls` (with the request's path added) are authenticated with it, a request sent straight to the host is not, and the value stays out of the sandbox unless a run asks for it with `mode: \"raw\"`. `raw: \"refused\"` means the value itself can never be given to a sandbox; `allowed` is the default. A sandbox given a secret bound to `api.openai.com` or `api.anthropic.com` also gets `OPENAI_BASE_URL` or `ANTHROPIC_BASE_URL` set to that address (the answer's `env` names each variable and its value), so those SDKs need no change. Setting a secret again keeps every binding field the request leaves out; `hosts: []` removes the binding.",
        "tags": [
          "Secrets"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SecretStored"
                },
                "example": {
                  "bytes": 51,
                  "created": true,
                  "env": {
                    "OPENAI_BASE_URL": "<the address promigence secrets set prints>/v1"
                  },
                  "hosts": [
                    "api.openai.com"
                  ],
                  "name": "OPENAI_API_KEY",
                  "next": [
                    "promigence run --snapshot <hash> --count 1 --cap 1 --secret OPENAI_API_KEY -- CMD"
                  ],
                  "placeholder": "sk-prom_ph_kdmfryeyl3gh6ycbrkxqzrnllb7ufqsxbkeebfnj",
                  "raw": "allowed",
                  "scan_responses": true,
                  "updated_at": "2026-09-19T09:14:02Z",
                  "urls": [
                    "<the address promigence secrets set prints>"
                  ]
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "413": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SecretSet"
              },
              "example": {
                "hosts": [
                  "api.openai.com"
                ],
                "name": "OPENAI_API_KEY",
                "value": "sk-example"
              }
            }
          }
        }
      }
    },
    "/v1/secrets/{name}": {
      "delete": {
        "operationId": "delete_v1_secrets_name",
        "summary": "Remove a secret.",
        "tags": [
          "Secrets"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SecretDeleted"
                },
                "example": {
                  "deleted": true,
                  "name": "OPENAI_API_KEY"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key"
      }
    },
    "/v1/snapshots": {
      "get": {
        "operationId": "get_v1_snapshots",
        "summary": "List snapshots, newest first. With a key: your org's plus every public one. Without a key: the public ones only — this is what `promigence examples` calls before you have signed in. Pages are `?limit=N` (1..=500, default 50) and `?cursor=`; echo back `next_cursor` and stop when it is `null`.",
        "tags": [
          "Snapshots"
        ],
        "security": [],
        "parameters": [
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SnapshotList"
                },
                "example": {
                  "limit": 50,
                  "next_cursor": null,
                  "snapshots": [
                    {
                      "alias": "better-auth@main",
                      "build_id": "bld_71ac30",
                      "commit": "4f1b6e2c9a0d7e35b81cf40a2d6e9b7c3a5f1d82",
                      "created_at": "2026-09-18T11:02:44Z",
                      "last_verified_at": "2026-09-19T08:00:00Z",
                      "repo": "https://github.com/better-auth/better-auth",
                      "setup": [
                        "pnpm install --frozen-lockfile"
                      ],
                      "snapshot_id": "snap_c0ffee",
                      "source": {
                        "commit": "4f1b6e2c9a0d7e35b81cf40a2d6e9b7c3a5f1d82",
                        "kind": "repo",
                        "repo": "https://github.com/better-auth/better-auth"
                      },
                      "tier": "standard",
                      "tier_assigned": "standard",
                      "verification": null,
                      "verified": true,
                      "verify": {
                        "allow_fast": false,
                        "cmd": "pnpm typecheck"
                      },
                      "visibility": "private"
                    }
                  ]
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "none"
      },
      "post": {
        "operationId": "post_v1_snapshots",
        "summary": "Build and verify a snapshot. Returns 202 with a `build_id`; poll it. A build is billed per second at its tier's rate while it runs, for at most `max_seconds`: `build_price` is the most it can cost. If `verify` exits non-zero nothing is stored, and the time the build ran is billed. Honours `Idempotency-Key`. A private repository is built through your GitHub or GitLab connection: `repo: \"github:owner/name\"` or `repo: \"gitlab:group/project\"` (subgroups too) with an optional `ref` (branch, tag or sha; default the default branch), `from` (the snapshot it starts from, default `promigence/base`) and `track` (with an `alias`: every push to the branch builds it again, each a normal build). A repository URL with credentials in it (a user name, password, token, query string or fragment) is refused with `repo_credentials_not_supported`.",
        "tags": [
          "Snapshots"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255,
              "pattern": "^[\\x21-\\x7E]+$"
            },
            "description": "Makes a retried create safe: send the same key on every attempt of ONE create and it starts, and bills, once. Kept 24 hours per org. The same key with the same request (method, path and JSON body) answers with the first answer — same status, same ids — marked `Idempotent-Replayed: true`. The same key with a different request is refused with 409 `idempotency_key_reused`. A repeat that arrives while the first is still running waits for its answer, or gets 409 `idempotency_key_in_use` with `Retry-After`. Only an answer that started something is kept: a create refused before anything started leaves the key free. The SDKs send one for every create they make."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SnapshotCreated"
                },
                "example": {
                  "alias": "better-auth@main",
                  "build_id": "bld_71ac30",
                  "build_price": 0.1656,
                  "commit": "4f1b6e2c9a0d7e35b81cf40a2d6e9b7c3a5f1d82",
                  "idempotent_replay": false,
                  "max_seconds": 3600,
                  "next": [
                    "promigence snapshot status bld_71ac30 --wait"
                  ],
                  "per_second_usd": 0.000046,
                  "repo": "https://github.com/better-auth/better-auth",
                  "source": {
                    "commit": "4f1b6e2c9a0d7e35b81cf40a2d6e9b7c3a5f1d82",
                    "kind": "repo",
                    "repo": "https://github.com/better-auth/better-auth"
                  },
                  "state": "running",
                  "tier": "standard",
                  "verified": true
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              },
              "Idempotent-Replayed": {
                "$ref": "#/components/headers/Idempotent-Replayed"
              }
            }
          },
          "202": {
            "description": "Accepted",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SnapshotCreated"
                },
                "example": {
                  "alias": "better-auth@main",
                  "build_id": "bld_71ac30",
                  "build_price": 0.1656,
                  "commit": "4f1b6e2c9a0d7e35b81cf40a2d6e9b7c3a5f1d82",
                  "idempotent_replay": false,
                  "max_seconds": 3600,
                  "next": [
                    "promigence snapshot status bld_71ac30 --wait"
                  ],
                  "per_second_usd": 0.000046,
                  "repo": "https://github.com/better-auth/better-auth",
                  "source": {
                    "commit": "4f1b6e2c9a0d7e35b81cf40a2d6e9b7c3a5f1d82",
                    "kind": "repo",
                    "repo": "https://github.com/better-auth/better-auth"
                  },
                  "state": "running",
                  "tier": "standard",
                  "verified": true
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              },
              "Idempotent-Replayed": {
                "$ref": "#/components/headers/Idempotent-Replayed"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "413": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key",
        "x-promigence-status": 202,
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SnapshotCreate"
              },
              "example": {
                "alias": "better-auth",
                "commit": "08fb47370c1c2f0a5f7fd3b0a2c9ee1d4b6a8c30",
                "repo": "https://github.com/better-auth/better-auth",
                "setup": [
                  "bun install --frozen-lockfile"
                ],
                "tier": "medium",
                "verify": "bun typecheck"
              }
            }
          }
        }
      }
    },
    "/v1/snapshots/{id}": {
      "delete": {
        "operationId": "delete_v1_snapshots_id",
        "summary": "Remove one of your own snapshots from your catalogue. The record goes and the space is reclaimed; finished runs keep their reports, so last month's numbers stay readable. Refused while a sandbox forked from it is still running — kill those first.",
        "tags": [
          "Snapshots"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SnapshotDeleted"
                },
                "example": {
                  "alias": "better-auth@main",
                  "deleted": true,
                  "ok": true,
                  "snapshot_id": "snap_c0ffee"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key"
      },
      "get": {
        "operationId": "get_v1_snapshots_id",
        "summary": "One snapshot by id or alias. `unavailable` is set, with the reason, when this snapshot can no longer be started; it is absent while it can.",
        "tags": [
          "Snapshots"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SnapshotView"
                },
                "example": {
                  "alias": "better-auth@main",
                  "build_id": "bld_71ac30",
                  "commit": "4f1b6e2c9a0d7e35b81cf40a2d6e9b7c3a5f1d82",
                  "created_at": "2026-09-18T11:02:44Z",
                  "last_verified_at": "2026-09-19T08:00:00Z",
                  "repo": "https://github.com/better-auth/better-auth",
                  "setup": [
                    "pnpm install --frozen-lockfile"
                  ],
                  "snapshot_id": "snap_c0ffee",
                  "source": {
                    "commit": "4f1b6e2c9a0d7e35b81cf40a2d6e9b7c3a5f1d82",
                    "kind": "repo",
                    "repo": "https://github.com/better-auth/better-auth"
                  },
                  "tier": "standard",
                  "tier_assigned": "standard",
                  "verification": null,
                  "verified": true,
                  "verify": {
                    "allow_fast": false,
                    "cmd": "pnpm typecheck"
                  },
                  "visibility": "private"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key"
      }
    },
    "/v1/snapshots/{id}/alias": {
      "put": {
        "operationId": "put_v1_snapshots_id_alias",
        "summary": "Move the snapshot's alias. The alias is mutable; the snapshot id and its hash are not.",
        "tags": [
          "Snapshots"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SnapshotView"
                },
                "example": {
                  "alias": "better-auth@main",
                  "build_id": "bld_71ac30",
                  "commit": "4f1b6e2c9a0d7e35b81cf40a2d6e9b7c3a5f1d82",
                  "created_at": "2026-09-18T11:02:44Z",
                  "last_verified_at": "2026-09-19T08:00:00Z",
                  "repo": "https://github.com/better-auth/better-auth",
                  "setup": [
                    "pnpm install --frozen-lockfile"
                  ],
                  "snapshot_id": "snap_c0ffee",
                  "source": {
                    "commit": "4f1b6e2c9a0d7e35b81cf40a2d6e9b7c3a5f1d82",
                    "kind": "repo",
                    "repo": "https://github.com/better-auth/better-auth"
                  },
                  "tier": "standard",
                  "tier_assigned": "standard",
                  "verification": null,
                  "verified": true,
                  "verify": {
                    "allow_fast": false,
                    "cmd": "pnpm typecheck"
                  },
                  "visibility": "private"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "413": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SnapshotAliasSet"
              },
              "example": {
                "alias": "better-auth-v2"
              }
            }
          }
        }
      }
    },
    "/v1/snapshots/{id}/manifest": {
      "get": {
        "operationId": "get_v1_snapshots_id_manifest",
        "summary": "The manifest: what a `.promigence` bundle is built from. Reachable without a key for public snapshots only.",
        "tags": [
          "Snapshots"
        ],
        "security": [],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SealedManifestView"
                },
                "example": {
                  "cached_at": "2026-09-18T11:05:09Z",
                  "manifest": {
                    "alias": "better-auth@main",
                    "id": "snap_c0ffee",
                    "manifest_hash": "blake3:0000000000000000000000000000000000000000000000000000000000000000",
                    "provenance": {
                      "built_at": "",
                      "commit": "",
                      "dpkg": "",
                      "ecosystem": "",
                      "egress": [],
                      "lockfile": {
                        "digest": "",
                        "frozen": false,
                        "path": ""
                      },
                      "repo": "",
                      "setup": [],
                      "toolchain": {},
                      "verify": {
                        "allow_fast": false,
                        "cmd": ""
                      }
                    },
                    "schema": "promigence.snapshot/v1",
                    "sealed": {
                      "layers": "blake3:00",
                      "machine": "blake3:00",
                      "platform": "blake3:00"
                    },
                    "verification": {
                      "concurrency": {},
                      "disk_used_mib": 0,
                      "fits_tier": "",
                      "guards": [],
                      "output_digest": "",
                      "peak_mem_mib": 0,
                      "verified_paths": [],
                      "verify_cold_ms": 0,
                      "verify_exit": 0,
                      "verify_warm": {
                        "cpu_ms": 0,
                        "median_ms": 0,
                        "n": 0
                      },
                      "verify_warm_builder": {
                        "median_ms": 0,
                        "n": 0
                      },
                      "verify_warm_first": {
                        "cpu_ms": 0,
                        "wall_ms": 0
                      }
                    }
                  },
                  "snapshot_id": "snap_c0ffee"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "none"
      }
    },
    "/v1/snapshots/{id}/verify": {
      "post": {
        "operationId": "post_v1_snapshots_id_verify",
        "summary": "Re-run the snapshot's own verify command in a fresh fork. Costs one sandbox's worth of seconds; it is a real run under the hood.",
        "tags": [
          "Snapshots"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "wait_ms",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255,
              "pattern": "^[\\x21-\\x7E]+$"
            },
            "description": "Makes a retried create safe: send the same key on every attempt of ONE create and it starts, and bills, once. Kept 24 hours per org. The same key with the same request (method, path and JSON body) answers with the first answer — same status, same ids — marked `Idempotent-Replayed: true`. The same key with a different request is refused with 409 `idempotency_key_reused`. A repeat that arrives while the first is still running waits for its answer, or gets 409 `idempotency_key_in_use` with `Retry-After`. Only an answer that started something is kept: a create refused before anything started leaves the key free. The SDKs send one for every create they make."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SnapshotVerifyStarted"
                },
                "example": {
                  "alias": "better-auth@main",
                  "count": 1,
                  "idempotent_replay": false,
                  "last_verified_at": "2026-09-19T08:00:00Z",
                  "launched": 1,
                  "per_second_usd": 0.000168,
                  "preemptible": false,
                  "price": 0.1512,
                  "quote": {
                    "breakdown": [
                      {
                        "per_second_usd": 0.000168,
                        "sandbox_count": 1,
                        "seconds_per_sandbox": 900
                      }
                    ],
                    "gib_second_usd": 0.0000045,
                    "max_cost": 0.1512,
                    "mem_gib": 16,
                    "per_second_usd": 0.000168,
                    "seconds_per_sandbox": 900,
                    "vcpu_second_usd": 0.000014,
                    "vcpus": 8
                  },
                  "run_id": "run_4b91de",
                  "sandboxes": [
                    {
                      "committed_seconds": 900,
                      "eta_s": 90,
                      "one_time": true,
                      "queued_message": "making room for you, ready in about 2 min. Once that is done, the rest of this run starts at once.",
                      "queued_reason": "capacity_arriving",
                      "sandbox_id": "sbx_8f2c1a",
                      "state": "queued"
                    }
                  ],
                  "seconds": 900,
                  "snapshot": "snap_c0ffee",
                  "snapshot_arg": "better-auth@main",
                  "snapshot_id": "snap_c0ffee",
                  "spend_cap": 5,
                  "state": "running",
                  "tier": "standard",
                  "timeout_ms": 900000,
                  "verify": "pnpm typecheck",
                  "warnings": [
                    "1 of 1 queued: making room for you, ready in about 2 min. Once that is done, the rest of this run starts at once."
                  ],
                  "workspace": "/work/repo"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              },
              "Idempotent-Replayed": {
                "$ref": "#/components/headers/Idempotent-Replayed"
              },
              "Promigence-Waited-Ms": {
                "$ref": "#/components/headers/Promigence-Waited-Ms"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "413": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SnapshotVerify"
              },
              "example": {
                "spend_cap": 1,
                "timeout_ms": 900000
              }
            }
          }
        }
      }
    },
    "/v1/snapshots/builds": {
      "get": {
        "operationId": "get_v1_snapshots_builds",
        "summary": "List your org's builds.",
        "tags": [
          "Snapshots"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0
            }
          },
          {
            "name": "state",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BuildList"
                },
                "example": {
                  "builds": [
                    {
                      "alias": "better-auth@main",
                      "billable_seconds": 145,
                      "build_id": "bld_71ac30",
                      "build_price": 0.1656,
                      "commit": "4f1b6e2c9a0d7e35b81cf40a2d6e9b7c3a5f1d82",
                      "cost_usd": 0.00667,
                      "created_at": "2026-09-18T11:02:44Z",
                      "error": null,
                      "finished_at": "2026-09-18T11:05:09Z",
                      "max_seconds": 3600,
                      "next": [
                        "promigence snapshot inspect snap_c0ffee"
                      ],
                      "per_second_usd": 0.000046,
                      "repo": "https://github.com/better-auth/better-auth",
                      "setup": [
                        "pnpm install --frozen-lockfile"
                      ],
                      "snapshot_id": "snap_c0ffee",
                      "source": {
                        "commit": "4f1b6e2c9a0d7e35b81cf40a2d6e9b7c3a5f1d82",
                        "kind": "repo",
                        "repo": "https://github.com/better-auth/better-auth"
                      },
                      "state": "verified",
                      "tier": "standard",
                      "tier_assigned": "standard",
                      "verification": null,
                      "verified": true,
                      "verify": "pnpm typecheck"
                    }
                  ],
                  "next_cursor": null
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key"
      }
    },
    "/v1/snapshots/builds/{id}": {
      "get": {
        "operationId": "get_v1_snapshots_builds_id",
        "summary": "One build. `?wait_ms=N` long-polls until the build reaches a terminal state, capped at 30 s server-side.",
        "tags": [
          "Snapshots"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "wait_ms",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BuildView"
                },
                "example": {
                  "alias": "better-auth@main",
                  "billable_seconds": 145,
                  "build_id": "bld_71ac30",
                  "build_price": 0.1656,
                  "commit": "4f1b6e2c9a0d7e35b81cf40a2d6e9b7c3a5f1d82",
                  "cost_usd": 0.00667,
                  "created_at": "2026-09-18T11:02:44Z",
                  "error": null,
                  "finished_at": "2026-09-18T11:05:09Z",
                  "max_seconds": 3600,
                  "next": [
                    "promigence snapshot inspect snap_c0ffee"
                  ],
                  "per_second_usd": 0.000046,
                  "repo": "https://github.com/better-auth/better-auth",
                  "setup": [
                    "pnpm install --frozen-lockfile"
                  ],
                  "snapshot_id": "snap_c0ffee",
                  "source": {
                    "commit": "4f1b6e2c9a0d7e35b81cf40a2d6e9b7c3a5f1d82",
                    "kind": "repo",
                    "repo": "https://github.com/better-auth/better-auth"
                  },
                  "state": "verified",
                  "tier": "standard",
                  "tier_assigned": "standard",
                  "verification": null,
                  "verified": true,
                  "verify": "pnpm typecheck"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              },
              "Promigence-Waited-Ms": {
                "$ref": "#/components/headers/Promigence-Waited-Ms"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key"
      }
    },
    "/v1/snapshots/builds/{id}/build-log": {
      "get": {
        "operationId": "get_v1_snapshots_builds_id_build_log",
        "summary": "The tail of the build log. `?tail=N` lines.",
        "tags": [
          "Snapshots"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "tail",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BuildLogView"
                },
                "example": {
                  "build_id": "bld_71ac30",
                  "log": [
                    "Lockfile is up to date, resolution step is skipped",
                    "Packages: +1204",
                    "Done in 41.2s"
                  ],
                  "state": "running"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "key"
      }
    },
    "/v1/status": {
      "get": {
        "operationId": "get_v1_status",
        "summary": "24 hours of synthetic check results plus service health, as JSON. This is what the status page reads.",
        "tags": [
          "Meta"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StatusSummary"
                },
                "example": {
                  "checks": {
                    "buckets_15m": [
                      [
                        3,
                        3
                      ],
                      [
                        3,
                        2
                      ]
                    ],
                    "checks": 288,
                    "e2e_ms": {
                      "max": 1204,
                      "p50": 412,
                      "p95": 688
                    },
                    "failures": [
                      {
                        "api_ok": true,
                        "at": "2026-09-19T03:29:41Z",
                        "step": "exec"
                      }
                    ],
                    "last": {
                      "age_s": 41,
                      "api_ok": true,
                      "at": "2026-09-19T09:14:39Z",
                      "e2e_ms": 402,
                      "ok": true,
                      "step": "done"
                    },
                    "ok": 287,
                    "since": "2026-09-18T09:14:39Z",
                    "success_pct": 99.65277777777777
                  },
                  "generated_at": "2026-09-19T09:14:39Z",
                  "service": "Promigence API",
                  "services": [
                    {
                      "last_health_at": "2026-09-19T09:14:39Z",
                      "name": "api",
                      "state": "up"
                    },
                    {
                      "last_health_at": "2026-09-19T09:14:39Z",
                      "name": "sandboxes",
                      "state": "up"
                    }
                  ],
                  "version": "0.0.1"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "none"
      }
    },
    "/v1/templates": {
      "get": {
        "operationId": "get_v1_templates",
        "summary": "The templates: ready-made starting points to fork (languages, app starters, agent tools, benchmarks). Each names the snapshot to fork, its version, what it starts from, and a count of what it has installed. No key needed.",
        "tags": [
          "Snapshots"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TemplateList"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "none"
      }
    },
    "/v1/templates/{name}": {
      "get": {
        "operationId": "get_v1_templates_name",
        "summary": "One template: its setup steps, everything it has installed (each package and its version, by package manager, and each tool's version), and every version with what changed. A newer version, or one that fixes a security problem, is listed here first. No key needed.",
        "tags": [
          "Snapshots"
        ],
        "security": [],
        "parameters": [
          {
            "name": "name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TemplateDetail"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "X-Client-Request-Id": {
                "$ref": "#/components/headers/X-Client-Request-Id"
              },
              "Promigence-Notice": {
                "$ref": "#/components/headers/Promigence-Notice"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$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"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-promigence-auth": "none"
      }
    }
  },
  "components": {
    "securitySchemes": {
      "apiKey": {
        "type": "http",
        "scheme": "bearer",
        "description": "`Authorization: Bearer prom_api_…` — an org API key."
      },
      "identityToken": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT",
        "description": "A sign-in identity token rather than an API key: what `POST /v1/auth/session` exchanges for a key, and what the organisation routes that act for a signed-in person take."
      }
    },
    "headers": {
      "X-Request-Id": {
        "description": "This answer's id. Also in an error's body as `request_id`; quote it when reporting a problem.",
        "schema": {
          "type": "string"
        }
      },
      "X-Client-Request-Id": {
        "description": "Your own `X-Request-Id`, echoed back when you sent one (up to 128 characters of letters, digits and `._:-`); with no `X-Request-Id`, an id you sent as `X-Client-Request-Id` is echoed instead. It never replaces ours.",
        "schema": {
          "type": "string"
        }
      },
      "Promigence-Notice": {
        "description": "A notice for your account (a maintenance window, an incident, the end of a trial), as compact JSON: the same object `GET /v1/me` returns as `notice`. Sent on every answer while one applies to you.",
        "schema": {
          "type": "string"
        }
      },
      "Retry-After": {
        "description": "Seconds to wait before sending the same request again: on `429`, on a `503` refusal, and on `409 idempotency_key_in_use`. The error's `retryable` says whether sending it again can help.",
        "schema": {
          "type": "integer",
          "minimum": 0
        }
      },
      "Idempotent-Replayed": {
        "description": "`true` when this answer is the stored answer to an earlier request with the same `Idempotency-Key`: nothing new was started.",
        "schema": {
          "type": "string"
        }
      },
      "Promigence-Waited-Ms": {
        "description": "How long the server held this request for `wait_ms`, in milliseconds. Absent when the request did not ask to wait.",
        "schema": {
          "type": "integer",
          "minimum": 0
        }
      },
      "X-Promigence-Path": {
        "description": "The file's path, as read.",
        "schema": {
          "type": "string"
        }
      },
      "X-Promigence-Size": {
        "description": "The file's size in bytes; the body is that many bytes unless a range was asked for.",
        "schema": {
          "type": "integer",
          "minimum": 0
        }
      },
      "Deprecation": {
        "description": "This operation is deprecated: `@<unix seconds>` of the day it was (RFC 9745). It keeps working until `Sunset`; the `Link` header says what replaces it.",
        "schema": {
          "type": "string"
        }
      },
      "Sunset": {
        "description": "The first day this deprecated operation may stop working, as an HTTP date (RFC 8594).",
        "schema": {
          "type": "string"
        }
      },
      "Link": {
        "description": "`<url>; rel=\"deprecation\"`: where the deprecation and its replacement are described.",
        "schema": {
          "type": "string"
        }
      }
    },
    "responses": {
      "Error": {
        "description": "The error envelope. The HTTP status is the code's `http` in `x-promigence-error-codes`, so a code and a status always agree.",
        "headers": {
          "X-Request-Id": {
            "$ref": "#/components/headers/X-Request-Id"
          },
          "X-Client-Request-Id": {
            "$ref": "#/components/headers/X-Client-Request-Id"
          },
          "Promigence-Notice": {
            "$ref": "#/components/headers/Promigence-Notice"
          },
          "Retry-After": {
            "$ref": "#/components/headers/Retry-After"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      }
    },
    "schemas": {
      "ErrorCode": {
        "type": "string",
        "description": "Every error code the API returns. `category` decides whether the failure is billed: `env` is ours (not billed before hand-over; after it, the time since the sandbox's last snapshot is credited back, up to 24 hours, when our side shows the cause), `task` is your command and is billed. The full table is `x-promigence-error-codes` at the document root.",
        "enum": [
          "fork_failed",
          "start_timeout",
          "readiness_failed",
          "verify_too_slow",
          "verify_each_failed",
          "toolchain_mismatch",
          "sandbox_unresponsive",
          "oom_within_tier",
          "disk_full_within_tier",
          "sandbox_interrupted",
          "integrity_mismatch",
          "egress_unavailable",
          "service_timeout",
          "preempted",
          "verify_did_not_cover",
          "grader_failed",
          "nonzero_exit",
          "grade_not_passed",
          "task_timeout",
          "oom_over_tier",
          "disk_over_tier",
          "shutdown_by_task",
          "modified_by_task",
          "cap_killed",
          "cap_exceeded",
          "cap_paused",
          "credits_paused",
          "aborted_by_client",
          "stopped_by_support",
          "expired",
          "not_started",
          "superseded",
          "usage",
          "internal",
          "auth",
          "forbidden",
          "not_found",
          "unreachable",
          "rate_limited",
          "timeout",
          "not_verified",
          "snapshot_incompatible",
          "storage_limit_reached",
          "resume_unavailable",
          "sandbox_unreachable",
          "capacity_busy",
          "region_at_capacity",
          "builder_unavailable",
          "builder_busy",
          "overloaded",
          "tier_unavailable",
          "snapshot_unavailable",
          "capacity_limit",
          "build_timeout",
          "dockerfile_build_failed",
          "image_unresolvable",
          "registry_unavailable",
          "enoent",
          "trial_credits_exhausted",
          "credit_unclaimed",
          "setup_required",
          "card_required",
          "billing_unavailable",
          "concurrency_limit",
          "egress_cap_reached",
          "project_cap_reached",
          "spend_limit_reached",
          "billing_hold",
          "tier_over_plan",
          "network_host_refused",
          "network_policy_unsupported",
          "secrets_in_snapshot",
          "secrets_unavailable",
          "secret_binding_unsupported",
          "idempotency_key_reused",
          "idempotency_key_in_use",
          "repo_credentials_not_supported",
          "account_exists",
          "invite_invalid",
          "invite_required",
          "key_expired",
          "account_blocked"
        ],
        "x-promigence-open-enum": true
      },
      "ErrorBody": {
        "type": "object",
        "description": "What went wrong, what to do about it, and what to exit with. `message` and `fix` are rendered from the code's templates (`x-promigence-error-codes`) with the request's own evidence substituted, so they are specific rather than generic.",
        "properties": {
          "code": {
            "$ref": "#/components/schemas/ErrorCode"
          },
          "message": {
            "type": "string",
            "description": "What happened."
          },
          "fix": {
            "type": "string",
            "description": "What to do about it."
          },
          "docs": {
            "type": "string",
            "format": "uri",
            "description": "The code's entry in the docs."
          },
          "exit": {
            "type": "integer",
            "description": "The CLI exit code for this class of failure."
          },
          "category": {
            "$ref": "#/components/schemas/FailureCategory",
            "description": "Whose failure it was: `env` is ours (credited back when our side shows the cause), `task` is your command's, `cap` a spend limit, `other` a refusal of the request itself. The code's `category` in `x-promigence-error-codes`. Branch on this and on the HTTP status as well as on the code: new codes are added."
          },
          "retryable": {
            "type": "boolean",
            "description": "True when nothing of yours ran and the same request, sent again unchanged, can succeed: after `Retry-After` when the answer has that header, else after a backoff. False when something must change first, and when the request may already have done its work (`unreachable`, `internal`, a failure after the command started): resend those only if they are safe to repeat (a read, a create with an `Idempotency-Key`)."
          },
          "evidence": {
            "type": "object",
            "additionalProperties": true,
            "description": "The values substituted into `message` and `fix`, filtered to what a customer may see."
          },
          "request_id": {
            "type": "string",
            "description": "This answer's id, also sent as the `X-Request-Id` header. Quote it when reporting a problem."
          }
        },
        "required": [
          "code",
          "message",
          "fix",
          "category",
          "retryable"
        ]
      },
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "$ref": "#/components/schemas/ErrorBody"
          }
        },
        "required": [
          "error"
        ]
      },
      "ArchiveInfo": {
        "description": "The reply to `POST /v1/sandboxes/:id/files/archive`.\n\n`archive_path` and `size` are the whole point: the tar is **inside the sandbox**, and these\ntwo are what drive the ordinary chunked file read that brings it out.",
        "properties": {
          "archive_path": {
            "description": "Where the tar landed inside the sandbox.",
            "type": "string"
          },
          "sandbox_id": {
            "type": "string"
          },
          "served_by": {
            "type": [
              "string",
              "null"
            ]
          },
          "size": {
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "source": {
            "description": "The directory that was packed.",
            "type": "string"
          }
        },
        "required": [
          "sandbox_id",
          "source",
          "archive_path",
          "size"
        ],
        "type": "object"
      },
      "AuditEntry": {
        "description": "One entry of an organization's audit log.",
        "properties": {
          "action": {
            "description": "What happened, e.g. `org.member.remove`, `key.create`, `org.invite.accept`.",
            "type": "string"
          },
          "actor": {
            "description": "Who acted: a member's email (or `api key` for a key with no person behind it) for a\ncustomer action, `Promigence support` for a support one, `Promigence` for the system's.",
            "type": "string"
          },
          "actor_type": {
            "description": "`customer` (a member), `support` (Promigence support) or `system`.",
            "type": "string"
          },
          "at": {
            "description": "RFC 3339.",
            "type": "string"
          },
          "ip": {
            "description": "The address the request came from; empty unless `actor_type` is `customer`.",
            "type": "string"
          },
          "outcome": {
            "description": "`ok`, `denied` or `failed`.",
            "type": "string"
          },
          "seq": {
            "description": "Cursor: pass it as `before` for the next (older) page.",
            "format": "int64",
            "type": "integer"
          },
          "target_id": {
            "type": "string"
          },
          "target_type": {
            "type": "string"
          }
        },
        "required": [
          "seq",
          "at",
          "action",
          "actor_type",
          "actor",
          "target_type",
          "target_id",
          "outcome",
          "ip"
        ],
        "type": "object"
      },
      "AuditList": {
        "description": "`GET /v1/orgs/{org_id}/audit`, newest first.",
        "properties": {
          "entries": {
            "items": {
              "$ref": "#/components/schemas/AuditEntry"
            },
            "type": "array"
          },
          "org_id": {
            "type": "string"
          }
        },
        "required": [
          "org_id",
          "entries"
        ],
        "type": "object"
      },
      "AuthConfig": {
        "description": "`GET /v1/auth/config` — what a client needs to start a sign-in.",
        "properties": {
          "authorize_url": {
            "type": "string"
          },
          "client_id": {
            "type": "string"
          },
          "console_authorize_url": {
            "description": "Where a command-line client sends the browser to have the signed-in person authorize it\n(`promigence login`): the client registers its request first (`POST /v1/auth/cli/requests`,\nwhich answers the page's address for it); the page shows the request and asks for a click,\nthen hands the client a one-time code it exchanges at `POST /v1/auth/cli/token`. Absent when\nthat page is not offered; a client then signs in through `authorize_url` as before.",
            "type": [
              "string",
              "null"
            ]
          },
          "identity_providers": {
            "additionalProperties": {
              "type": "string"
            },
            "description": "The sign-in methods to offer, as name -> label (`email`, `google`, `github`). A client that\nasks the sign-in pages for one method passes the label as their `identity_provider`, except\n`email`, which is the pages' own form and needs none.",
            "type": "object"
          },
          "invite_mode": {
            "default": false,
            "description": "True while new accounts need an invite code: a client redeems one\n(`POST /v1/auth/invite`) before it starts the sign-in (`promigence signup`). An existing\naccount signs in as before either way.",
            "type": "boolean"
          },
          "loopback_redirect_uris": {
            "description": "The redirect URIs a command-line client may listen on.",
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "paste_redirect_uri": {
            "description": "Where a headless sign-in lands instead, to show a code to paste back.",
            "type": "string"
          },
          "scopes": {
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "token_url": {
            "type": "string"
          }
        },
        "required": [
          "authorize_url",
          "token_url",
          "client_id",
          "scopes",
          "identity_providers",
          "loopback_redirect_uris",
          "paste_redirect_uri"
        ],
        "type": "object"
      },
      "AutoPauseMode": {
        "description": "What counts as idle: no API requests, or no activity inside the sandbox either.",
        "enum": [
          "requests",
          "activity"
        ],
        "type": "string",
        "x-promigence-open-enum": true
      },
      "AutoPauseSet": {
        "description": "The idle rule, as it now stands.",
        "properties": {
          "auto_pause_mode": {
            "description": "`requests` | `activity`.",
            "type": "string"
          },
          "auto_pause_s": {
            "description": "Park after this many idle seconds; 0 for never.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "ok": {
            "type": "boolean"
          },
          "sandbox_id": {
            "type": "string"
          }
        },
        "required": [
          "ok",
          "sandbox_id",
          "auto_pause_s",
          "auto_pause_mode"
        ],
        "type": "object"
      },
      "BackgroundExec": {
        "description": "A background command, as `GET /v1/sandboxes/{id}/execs/{exec_id}` reports it, and as the\n`202` from `POST /v1/sandboxes/{id}/execs` with `background: true` hands it over.\n\nThe output is fetched by byte range (`?stream=stdout|stderr&offset=&len=`), which is what\nfills `stream`, `offset`, `len`, `eof` and `data`; a status read carries none of them.",
        "properties": {
          "argv": {
            "description": "The command, as one line.",
            "type": [
              "string",
              "null"
            ]
          },
          "background": {
            "description": "Always true: this is the handle form of a command.",
            "type": "boolean"
          },
          "data": {
            "description": "The bytes, base64.",
            "type": [
              "string",
              "null"
            ]
          },
          "eof": {
            "description": "True when `data` reaches the end of what is held so far.",
            "type": [
              "boolean",
              "null"
            ]
          },
          "error": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/BackgroundExecError"
              },
              {
                "type": "null"
              }
            ],
            "description": "Why the command could not run; only when `state` is `failed`."
          },
          "exec_id": {
            "type": "string"
          },
          "exit": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/BackgroundExecExit"
              },
              {
                "type": "null"
              }
            ],
            "description": "How the command ended; only once `state` is `exited`."
          },
          "follow": {
            "description": "Started with `follow`: the newest output is kept, and the handle is freed 10 minutes\nafter the command ends.",
            "type": [
              "boolean",
              "null"
            ]
          },
          "idle_hold_s": {
            "description": "Present when the sandbox pauses itself when idle: after this command ends, the idle rule\nwaits up to this many seconds for its result to be read before it pauses the sandbox (a\npause drops the handle and its output). Reading its output once it has finished releases\nthe hold, and so does deleting the handle (`DELETE /v1/sandboxes/{id}/execs/{exec_id}`,\nCLI `exec kill EXEC --forget`).",
            "format": "uint64",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "idle_hold_until": {
            "description": "When this finished command stops holding the idle rule off (RFC 3339), while it still\ndoes: absent for a running command, once its output has been read, and once the time has\npassed.",
            "type": [
              "string",
              "null"
            ]
          },
          "len": {
            "description": "Bytes in `data`.",
            "format": "uint64",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "offset": {
            "format": "uint64",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "sandbox_id": {
            "type": "string"
          },
          "skipped": {
            "description": "A `follow` command only: bytes between the `offset` asked for and the first byte still\nheld, dropped to keep the newest output; `data` then starts at `offset + skipped`.",
            "format": "uint64",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "started_unix_ns": {
            "description": "Unix nanoseconds.",
            "format": "uint64",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "state": {
            "description": "`running` | `exited` | `failed`.",
            "type": "string"
          },
          "stderr_bytes": {
            "format": "uint64",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "stderr_total": {
            "format": "uint64",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "stdin_open": {
            "description": "True while the command's standard input can still be written to.",
            "type": [
              "boolean",
              "null"
            ]
          },
          "stdout_bytes": {
            "description": "Bytes of standard output held and readable by range.",
            "format": "uint64",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "stdout_total": {
            "description": "Bytes of standard output the command has written in total.",
            "format": "uint64",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "stream": {
            "description": "Which stream `data` is from: 1 for stdout, 2 for stderr.",
            "format": "uint8",
            "maximum": 255,
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "truncated": {
            "description": "True when more was written than is held.",
            "type": [
              "boolean",
              "null"
            ]
          },
          "waited_ms": {
            "description": "How long a `?wait_ms=` read waited, in milliseconds.",
            "format": "uint64",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          }
        },
        "required": [
          "sandbox_id",
          "background",
          "exec_id",
          "state"
        ],
        "type": "object"
      },
      "BackgroundExecError": {
        "description": "Why a background command could not run.",
        "properties": {
          "code": {
            "type": "string"
          },
          "msg": {
            "type": "string"
          }
        },
        "required": [
          "code",
          "msg"
        ],
        "type": "object"
      },
      "BackgroundExecExit": {
        "description": "How a background command ended.",
        "properties": {
          "cpu_ms": {
            "format": "double",
            "type": "number"
          },
          "exit_code": {
            "description": "`null` if a signal killed it.",
            "format": "int32",
            "type": [
              "integer",
              "null"
            ]
          },
          "max_rss_kib": {
            "description": "Peak resident memory, in kibibytes.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "oom_killed": {
            "description": "True when it was killed inside the sandbox for running out of memory.",
            "type": "boolean"
          },
          "signal": {
            "format": "int32",
            "type": [
              "integer",
              "null"
            ]
          },
          "truncated": {
            "type": "boolean"
          },
          "wall_ms": {
            "format": "double",
            "type": "number"
          }
        },
        "required": [
          "wall_ms",
          "cpu_ms",
          "max_rss_kib",
          "truncated",
          "oom_killed"
        ],
        "type": "object"
      },
      "BackgroundExecList": {
        "description": "`GET /v1/sandboxes/{id}/execs` — this sandbox's background commands.",
        "properties": {
          "execs": {
            "items": {
              "$ref": "#/components/schemas/BackgroundExec"
            },
            "type": "array"
          },
          "sandbox_id": {
            "type": "string"
          }
        },
        "required": [
          "sandbox_id",
          "execs"
        ],
        "type": "object"
      },
      "BillingHistory": {
        "description": "`GET /v1/billing/history` — your billing history, newest first: every credit you received and\nevery payment, one page at a time.",
        "properties": {
          "entries": {
            "items": {
              "$ref": "#/components/schemas/BillingHistoryEntry"
            },
            "type": "array"
          },
          "next_cursor": {
            "description": "Pass as `cursor` for the next, older page; `null` on the last page.",
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "entries"
        ],
        "type": "object"
      },
      "BillingHistoryEntry": {
        "description": "One entry of your billing history: a credit you received or a payment. Exactly one of\n`credit` and `payment` is set.",
        "properties": {
          "at": {
            "description": "When it happened, RFC 3339: when a credit was added, when a payment was made, failed or\nwas refunded.",
            "type": "string"
          },
          "credit": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/CreditGrant"
              },
              {
                "type": "null"
              }
            ],
            "description": "A credit you received; `null` for a payment."
          },
          "payment": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Payment"
              },
              {
                "type": "null"
              }
            ],
            "description": "A payment; `null` for a credit."
          }
        },
        "required": [
          "at"
        ],
        "type": "object"
      },
      "BillingPeriod": {
        "description": "The billing period `usage` covers.",
        "properties": {
          "basis": {
            "description": "`utc_calendar_month`.",
            "type": "string"
          },
          "end": {
            "description": "RFC 3339, exclusive.",
            "type": "string"
          },
          "start": {
            "description": "RFC 3339.",
            "type": "string"
          }
        },
        "required": [
          "start",
          "end",
          "basis"
        ],
        "type": "object"
      },
      "BillingStatus": {
        "description": "`GET /v1/billing` — plan, card on file, this month's usage, and the upcoming invoice preview.\nNever fails because the payment provider is slow: the estimate is the only part that asks it,\nand its failure is a field, not a status.",
        "properties": {
          "billing_enabled": {
            "description": "False while card billing is not available.",
            "type": "boolean"
          },
          "card": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/CardOnFile"
              },
              {
                "type": "null"
              }
            ],
            "description": "`null` while no card is on file."
          },
          "card_note": {
            "description": "A sentence to show beside the card when it does not unlock paid limits for this\norganization (it already pays for another one, or it is being confirmed with a $1 charge, or\nthat charge did not go through); `null` otherwise.",
            "type": [
              "string",
              "null"
            ]
          },
          "card_on_file": {
            "type": "boolean"
          },
          "customer": {
            "description": "True once a billing customer exists for the organisation.",
            "type": "boolean"
          },
          "method_check": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/MethodCheckView"
              },
              {
                "type": "null"
              }
            ],
            "default": null,
            "description": "The $1 that confirms the payment method on file when it has no stable payer (Apple Pay,\nGoogle Pay, Amazon Pay); `null` when it needed none."
          },
          "notice": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/TrialNotice"
              },
              {
                "type": "null"
              }
            ]
          },
          "org_id": {
            "type": "string"
          },
          "period": {
            "$ref": "#/components/schemas/BillingPeriod"
          },
          "plan": {
            "type": "string"
          },
          "suspend_reason": {
            "type": [
              "string",
              "null"
            ]
          },
          "suspended": {
            "type": "boolean"
          },
          "trial": {
            "$ref": "#/components/schemas/TrialStatus"
          },
          "upcoming_invoice": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/UpcomingInvoice"
              },
              {
                "type": "null"
              }
            ],
            "description": "The payment provider's estimate of the next invoice; `null` when there is no\nsubscription, or when the estimate could not be fetched (see `upcoming_invoice_error`)."
          },
          "upcoming_invoice_error": {
            "type": [
              "string",
              "null"
            ]
          },
          "usage": {
            "$ref": "#/components/schemas/PeriodUsage"
          }
        },
        "required": [
          "org_id",
          "billing_enabled",
          "plan",
          "card_on_file",
          "customer",
          "suspended",
          "period",
          "usage",
          "trial"
        ],
        "type": "object"
      },
      "BuildJoined": {
        "description": "An identical build that was already in progress, answered as if it were the caller's own.",
        "properties": {
          "alias": {
            "description": "The name the snapshot holds now, or the one asked for while the build runs. `null` once\nthe snapshot is deleted: the name may belong to another snapshot by then.",
            "type": [
              "string",
              "null"
            ]
          },
          "alias_applied": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "alias_requested": {
            "description": "The alias that was asked for, when the build in progress was to carry another, or none.\nThe build carries it now (`alias_applied: true`) and its snapshot is stored under it;\n`warnings` names the alias the build was to carry.",
            "type": [
              "string",
              "null"
            ]
          },
          "billable_seconds": {
            "description": "Once the build has ended, the seconds it is billed for: the time it ran, whether it was\nstored, its own `setup` or `verify` failed, or it ran to its time limit; 0 when it failed\non our side. Absent while it is queued or running, and for a build priced per build.",
            "format": "uint64",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "build_id": {
            "type": "string"
          },
          "build_price": {
            "description": "The most the build can cost, in USD, as said when it was started: `max_seconds` at\n`per_second_usd`. What it was billed is `cost_usd`.",
            "format": "double",
            "type": "number"
          },
          "commit": {
            "type": "string"
          },
          "cost_usd": {
            "description": "Once the build has ended, what it cost in USD; 0 when nothing was charged. Absent while it\nis queued or running.",
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "created_at": {
            "description": "RFC 3339.",
            "type": "string"
          },
          "error": {
            "description": "Why it failed. `null` while it is going and for a build that worked."
          },
          "finished_at": {
            "description": "RFC 3339.",
            "type": [
              "string",
              "null"
            ]
          },
          "idempotent_replay": {
            "type": "boolean"
          },
          "idempotent_replay_age_s": {
            "description": "Present when `idempotent_replay` is true: how many seconds ago that first answer was\ngiven, so a client can say which earlier request this repeats.",
            "format": "uint64",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "joined": {
            "description": "Always true here.",
            "type": "boolean"
          },
          "max_seconds": {
            "description": "The longest the build may run, in seconds: it is billed for at most this long. Absent for\na build priced per build.",
            "format": "uint64",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "next": {
            "description": "What to do next, ready to run.",
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "per_second_usd": {
            "description": "What one second of the build costs, in USD: its tier's per-second rate. Absent for a build\npriced per build, before builds were billed per second.",
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "repo": {
            "type": "string"
          },
          "setup": {
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "snapshot_deleted": {
            "description": "`true` when the snapshot this build made has since been deleted. Absent otherwise.",
            "type": "boolean"
          },
          "snapshot_id": {
            "description": "The snapshot it produced; `null` until it is finished, and for a build that failed.",
            "type": [
              "string",
              "null"
            ]
          },
          "source": {
            "description": "What it is being built from. The `kind` field says which of the three forms it is."
          },
          "state": {
            "description": "`queued` | `running` | `verified` | `built` | `rejected` | `failed`. `built` is a\nfinished build that stored its snapshot with no verification command to run (an image\nbuilt without `verify`): done and ready to start, like `verified`, but nothing was\nverified.",
            "type": "string"
          },
          "tier": {
            "type": "string"
          },
          "tier_assigned": {
            "type": "string"
          },
          "verification": {
            "description": "What the verification command did. `null` until there is a snapshot to report it for."
          },
          "verified": {
            "description": "True when the build finished `verified` and its verification command passed. False while\nit is queued or running, when it failed or was rejected, and for an image built without\n`verify` (state `built`: stored, but nothing was verified). Nothing is stored if the\ncommand exits non-zero; the time the build ran is billed.",
            "type": "boolean"
          },
          "verify": {
            "description": "The verification command, as it was given.",
            "type": "string"
          },
          "warnings": {
            "items": {
              "type": "string"
            },
            "type": [
              "array",
              "null"
            ]
          }
        },
        "required": [
          "build_id",
          "state",
          "tier",
          "tier_assigned",
          "repo",
          "commit",
          "source",
          "verified",
          "setup",
          "verify",
          "build_price",
          "created_at",
          "next",
          "joined",
          "idempotent_replay"
        ],
        "type": "object"
      },
      "BuildList": {
        "description": "`GET /v1/snapshots/builds`.",
        "properties": {
          "builds": {
            "items": {
              "$ref": "#/components/schemas/BuildView"
            },
            "type": "array"
          },
          "next_cursor": {
            "default": null,
            "description": "Pass as `?cursor=` for the next page; `null` on the last one.",
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "builds"
        ],
        "type": "object"
      },
      "BuildLogView": {
        "description": "`GET /v1/snapshots/builds/{id}/build-log` — the end of one build's output.",
        "properties": {
          "build_id": {
            "type": "string"
          },
          "log": {
            "description": "The last `tail` lines of the build's output, oldest first. Empty while the build is\n`queued`.",
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "state": {
            "description": "`queued` | `running` | `verified` | `built` | `rejected` | `failed` (`built`: stored with\nno verification command to run).",
            "type": "string"
          }
        },
        "required": [
          "build_id",
          "state",
          "log"
        ],
        "type": "object"
      },
      "BuildQueued": {
        "description": "A build that was just started.",
        "properties": {
          "alias": {
            "type": [
              "string",
              "null"
            ]
          },
          "build_id": {
            "type": "string"
          },
          "build_price": {
            "description": "The most the build can cost, in USD, said before it runs: `max_seconds` at\n`per_second_usd`. It is billed per second for the time it runs.",
            "format": "double",
            "type": "number"
          },
          "commit": {
            "type": "string"
          },
          "idempotent_replay": {
            "description": "True when this is the stored answer to an `Idempotency-Key` that was seen before, and no\nsecond build was started.",
            "type": "boolean"
          },
          "idempotent_replay_age_s": {
            "description": "Present when `idempotent_replay` is true: how many seconds ago that first answer was\ngiven, so a client can say which earlier request this repeats.",
            "format": "uint64",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "max_seconds": {
            "description": "The longest the build may run, in seconds: it is billed for at most this long.",
            "format": "uint64",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "next": {
            "description": "What to do next, ready to run.",
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "per_second_usd": {
            "description": "What one second of the build costs, in USD: its tier's per-second rate.",
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "repo": {
            "type": "string"
          },
          "source": {
            "description": "What it is being built from. The `kind` field says which of the three forms it is."
          },
          "sources": {
            "description": "The extra repositories, normalised, when the build named any.",
            "items": {
              "$ref": "#/components/schemas/Source"
            },
            "type": "array"
          },
          "state": {
            "description": "`queued` | `running`.",
            "type": "string"
          },
          "tier": {
            "type": "string"
          },
          "verified": {
            "description": "True when a verification command was given.",
            "type": "boolean"
          }
        },
        "required": [
          "build_id",
          "state",
          "tier",
          "build_price",
          "repo",
          "commit",
          "source",
          "verified",
          "idempotent_replay",
          "next"
        ],
        "type": "object"
      },
      "BuildUsage": {
        "description": "Builds in the period.",
        "properties": {
          "amount": {
            "description": "USD.",
            "format": "double",
            "type": "number"
          },
          "count": {
            "format": "int64",
            "type": "integer"
          }
        },
        "required": [
          "count",
          "amount"
        ],
        "type": "object"
      },
      "BuildView": {
        "description": "One build: a snapshot being made, and whether it worked.",
        "properties": {
          "alias": {
            "description": "The name the snapshot holds now, or the one asked for while the build runs. `null` once\nthe snapshot is deleted: the name may belong to another snapshot by then.",
            "type": [
              "string",
              "null"
            ]
          },
          "billable_seconds": {
            "description": "Once the build has ended, the seconds it is billed for: the time it ran, whether it was\nstored, its own `setup` or `verify` failed, or it ran to its time limit; 0 when it failed\non our side. Absent while it is queued or running, and for a build priced per build.",
            "format": "uint64",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "build_id": {
            "type": "string"
          },
          "build_price": {
            "description": "The most the build can cost, in USD, as said when it was started: `max_seconds` at\n`per_second_usd`. What it was billed is `cost_usd`.",
            "format": "double",
            "type": "number"
          },
          "commit": {
            "type": "string"
          },
          "cost_usd": {
            "description": "Once the build has ended, what it cost in USD; 0 when nothing was charged. Absent while it\nis queued or running.",
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "created_at": {
            "description": "RFC 3339.",
            "type": "string"
          },
          "error": {
            "description": "Why it failed. `null` while it is going and for a build that worked."
          },
          "finished_at": {
            "description": "RFC 3339.",
            "type": [
              "string",
              "null"
            ]
          },
          "max_seconds": {
            "description": "The longest the build may run, in seconds: it is billed for at most this long. Absent for\na build priced per build.",
            "format": "uint64",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "next": {
            "description": "What to do next, ready to run.",
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "per_second_usd": {
            "description": "What one second of the build costs, in USD: its tier's per-second rate. Absent for a build\npriced per build, before builds were billed per second.",
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "repo": {
            "type": "string"
          },
          "setup": {
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "snapshot_deleted": {
            "description": "`true` when the snapshot this build made has since been deleted. Absent otherwise.",
            "type": "boolean"
          },
          "snapshot_id": {
            "description": "The snapshot it produced; `null` until it is finished, and for a build that failed.",
            "type": [
              "string",
              "null"
            ]
          },
          "source": {
            "description": "What it is being built from. The `kind` field says which of the three forms it is."
          },
          "state": {
            "description": "`queued` | `running` | `verified` | `built` | `rejected` | `failed`. `built` is a\nfinished build that stored its snapshot with no verification command to run (an image\nbuilt without `verify`): done and ready to start, like `verified`, but nothing was\nverified.",
            "type": "string"
          },
          "tier": {
            "type": "string"
          },
          "tier_assigned": {
            "type": "string"
          },
          "verification": {
            "description": "What the verification command did. `null` until there is a snapshot to report it for."
          },
          "verified": {
            "description": "True when the build finished `verified` and its verification command passed. False while\nit is queued or running, when it failed or was rejected, and for an image built without\n`verify` (state `built`: stored, but nothing was verified). Nothing is stored if the\ncommand exits non-zero; the time the build ran is billed.",
            "type": "boolean"
          },
          "verify": {
            "description": "The verification command, as it was given.",
            "type": "string"
          }
        },
        "required": [
          "build_id",
          "state",
          "tier",
          "tier_assigned",
          "repo",
          "commit",
          "source",
          "verified",
          "setup",
          "verify",
          "build_price",
          "created_at",
          "next"
        ],
        "type": "object"
      },
      "Capacity": {
        "description": "Whether this run's sandboxes can start, in the words a waiting caller needs.\n\nThree states: `ok` — nothing is waiting; `arriving` — sandboxes are waiting and should start\nwithin `eta_s`; `blocked` — they cannot start now, and the reason is named. A block is a\nrefusal, and it arrives at once rather than after a countdown.",
        "properties": {
          "awaiting_capacity": {
            "description": "How many sandboxes of this run are waiting for capacity.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "blocked": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/CapacityBlock"
              },
              {
                "type": "null"
              }
            ],
            "description": "Why the waiting sandboxes cannot start. `null` unless `state` is `blocked`."
          },
          "eta_s": {
            "description": "The soonest the waiting sandboxes can start, in seconds. Never null while `state` is\n`arriving`, and never zero.",
            "format": "uint64",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "queued_message": {
            "description": "The same, in words, with the time it should take: the `queued_message` they carry.",
            "type": [
              "string",
              "null"
            ]
          },
          "queued_reason": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/QueuedReason"
              },
              {
                "type": "null"
              }
            ],
            "description": "Why this run's waiting sandboxes are waiting, when it is known: the `queued_reason` they\ncarry. Absent otherwise."
          },
          "state": {
            "description": "`ok` | `arriving` | `blocked`.",
            "type": "string"
          }
        },
        "required": [
          "state",
          "awaiting_capacity"
        ],
        "type": "object"
      },
      "CapacityBlock": {
        "description": "Why the waiting sandboxes cannot start, named rather than implied.",
        "properties": {
          "at": {
            "description": "When it was hit, RFC 3339.",
            "type": "string"
          },
          "code": {
            "description": "The error code this refusal is reported as.",
            "type": "string"
          },
          "reason": {
            "description": "The error code's message, in the words the error reference gives it.",
            "type": "string"
          }
        },
        "required": [
          "code",
          "reason",
          "at"
        ],
        "type": "object"
      },
      "Capture": {
        "description": "What was preserved of a sandbox that ended, and until when.\n\n`snapshot_id` is the same kind of content hash every other snapshot carries, so \"here is the\nmachine at the moment it broke\" is verifiable rather than asserted. The service stores this\nand nothing else: no file content, no diff, no process output ever crosses the boundary.",
        "properties": {
          "bytes": {
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "expires_at": {
            "type": "string"
          },
          "snapshot_id": {
            "type": "string"
          }
        },
        "required": [
          "snapshot_id",
          "expires_at",
          "bytes"
        ],
        "type": "object"
      },
      "CaptureDeleted": {
        "description": "`DELETE /v1/captures/{id}` — a preserved failure destroyed now.",
        "properties": {
          "bytes": {
            "description": "Bytes freed.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "deleted": {
            "type": "boolean"
          },
          "deleted_at": {
            "description": "RFC 3339.",
            "type": "string"
          },
          "ok": {
            "type": "boolean"
          },
          "snapshot_id": {
            "type": "string"
          }
        },
        "required": [
          "ok",
          "snapshot_id",
          "deleted",
          "bytes",
          "deleted_at"
        ],
        "type": "object"
      },
      "CaptureList": {
        "description": "`GET /v1/runs/{id}/captures` — what is preserved of this run, and when it goes.",
        "properties": {
          "captures": {
            "items": {
              "$ref": "#/components/schemas/CaptureView"
            },
            "type": "array"
          },
          "ok": {
            "type": "boolean"
          },
          "run_id": {
            "type": "string"
          }
        },
        "required": [
          "ok",
          "run_id",
          "captures"
        ],
        "type": "object"
      },
      "CaptureMode": {
        "description": "`POST /v1/runs {capture}`: whether a sandbox's state is\npreserved when it ends, so it can be reopened as a live sandbox at the moment it broke.\n\nThe default is **on_failure**, because a failure you cannot reopen is the one you will wish\nyou had kept and asking for the flag after the incident is too late. `Off` is for the customer\nwhose security review forbids retention of any kind.",
        "enum": [
          "on_failure",
          "off",
          "always"
        ],
        "type": "string",
        "x-promigence-open-enum": true
      },
      "CaptureView": {
        "description": "One preserved failure.",
        "properties": {
          "available": {
            "default": true,
            "description": "Whether `POST /v1/runs/{id}/open` can still open it. `false` once it has been lost before\nit expired; it is then listed for the record and cannot be opened.",
            "type": "boolean"
          },
          "bytes": {
            "description": "What it occupies on disk.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "captured_at": {
            "description": "RFC 3339.",
            "type": "string"
          },
          "code": {
            "description": "Its failure code.",
            "type": "string"
          },
          "expires_at": {
            "description": "When it is destroyed at the latest, RFC 3339. It can stop being openable sooner:\n`available` says whether it still can be.",
            "type": "string"
          },
          "outcome": {
            "type": "string"
          },
          "run_id": {
            "type": "string"
          },
          "sandbox_id": {
            "description": "The sandbox whose state this is.",
            "type": "string"
          },
          "snapshot_id": {
            "description": "The id to pass to `POST /v1/runs/{id}/open` and `DELETE /v1/captures/{id}`.",
            "type": "string"
          }
        },
        "required": [
          "snapshot_id",
          "run_id",
          "sandbox_id",
          "outcome",
          "code",
          "bytes",
          "captured_at",
          "expires_at"
        ],
        "type": "object"
      },
      "CardOnFile": {
        "description": "The card on file, enough to recognise it.",
        "properties": {
          "brand": {
            "description": "The card's brand (`visa`, `mastercard`, ...); for a card held in a wallet, the wallet\n(`apple_pay`, `google_pay`); for another payment method, its kind (`link`, `cashapp`,\n`amazon_pay`).",
            "type": [
              "string",
              "null"
            ]
          },
          "last4": {
            "description": "The card's last four digits; `null` for a payment method without a card number.",
            "type": [
              "string",
              "null"
            ]
          }
        },
        "type": "object"
      },
      "CheckFailure": {
        "description": "One failed synthetic check.",
        "properties": {
          "api_ok": {
            "type": "boolean"
          },
          "at": {
            "description": "RFC 3339.",
            "type": "string"
          },
          "step": {
            "description": "The step it failed at.",
            "type": "string"
          }
        },
        "required": [
          "at",
          "api_ok",
          "step"
        ],
        "type": "object"
      },
      "CheckWindow": {
        "description": "The last 24 hours of synthetic checks: totals, latency percentiles, fifteen-minute buckets\nand the most recent failures.",
        "properties": {
          "buckets_15m": {
            "description": "96 buckets of fifteen minutes, oldest first: `[checks, passed]`.",
            "items": {
              "items": {
                "format": "uint64",
                "minimum": 0,
                "type": "integer"
              },
              "maxItems": 2,
              "minItems": 2,
              "type": "array"
            },
            "type": "array"
          },
          "checks": {
            "description": "Checks run in the window.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "e2e_ms": {
            "$ref": "#/components/schemas/LatencyStats",
            "description": "End-to-end latency of the passing checks, in milliseconds."
          },
          "failures": {
            "description": "The most recent failures, newest first, at most 20.",
            "items": {
              "$ref": "#/components/schemas/CheckFailure"
            },
            "type": "array"
          },
          "last": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/LastCheck"
              },
              {
                "type": "null"
              }
            ],
            "description": "The most recent check; `null` when none ran."
          },
          "ok": {
            "description": "Checks that passed.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "since": {
            "description": "Where the window starts, RFC 3339.",
            "type": "string"
          },
          "success_pct": {
            "description": "`null` when no check ran.",
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          }
        },
        "required": [
          "since",
          "checks",
          "ok",
          "e2e_ms",
          "buckets_15m",
          "failures"
        ],
        "type": "object"
      },
      "CheckoutSession": {
        "description": "`POST /v1/billing/checkout` — a card-setup checkout to send the customer to.",
        "properties": {
          "expires_at": {
            "description": "When the link stops working, RFC 3339.",
            "type": [
              "string",
              "null"
            ]
          },
          "mode": {
            "description": "`\"setup\"` — the checkout stores a card, it does not take a payment.",
            "type": "string"
          },
          "session_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "url": {
            "description": "Open this. Adding a card keeps any trial credit that is left.",
            "type": "string"
          }
        },
        "required": [
          "url",
          "mode"
        ],
        "type": "object"
      },
      "ClaimLink": {
        "description": "A single-use link to the page where the free credit is claimed (`POST /v1/credits/claim-link`).",
        "properties": {
          "expires_at": {
            "description": "RFC 3339.",
            "type": "string"
          },
          "url": {
            "description": "Open it in a browser. It works once, for 15 minutes.",
            "type": "string"
          }
        },
        "required": [
          "url",
          "expires_at"
        ],
        "type": "object"
      },
      "CliRequestCreate": {
        "additionalProperties": false,
        "description": "`POST /v1/auth/cli/requests`: a command-line client registers the sign-in it is about to ask a\nperson to authorize in the browser.",
        "properties": {
          "code_challenge": {
            "description": "`base64url(sha256(code_verifier))`: the PKCE challenge (RFC 7636), 43 characters.",
            "type": "string"
          },
          "code_challenge_method": {
            "description": "`S256`, the only method accepted.",
            "type": "string"
          },
          "device": {
            "description": "The computer's name, shown on the page as the client reports it (at most 64 characters).",
            "type": [
              "string",
              "null"
            ]
          },
          "key_name": {
            "description": "The new key's name (at most 64 characters; default `cli@<device>`).",
            "type": [
              "string",
              "null"
            ]
          },
          "port": {
            "description": "The local port the client listens on for the code: one of `GET /v1/auth/config`'s\n`loopback_redirect_uris`. Absent: the page shows the code, to paste into the client.",
            "format": "uint16",
            "maximum": 65535,
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "provider": {
            "description": "`github` or `google`: a browser that is not signed in goes straight to that sign-in method.",
            "type": [
              "string",
              "null"
            ]
          },
          "ref": {
            "description": "A referral code, applied if this sign-in creates the account.",
            "type": [
              "string",
              "null"
            ]
          },
          "state": {
            "description": "Handed back with the code, unchanged: 8 to 128 URL-safe characters.",
            "type": "string"
          }
        },
        "required": [
          "code_challenge",
          "code_challenge_method",
          "state"
        ],
        "type": "object"
      },
      "CliRequestCreated": {
        "description": "`POST /v1/auth/cli/requests` — a command-line client's sign-in request, registered: the page to\nopen in a browser, where the signed-in person sees the request (with when and from where it was\nmade) and authorizes it.",
        "properties": {
          "authorize_url": {
            "description": "The authorize page for this request.",
            "type": "string"
          },
          "expires_in_s": {
            "description": "Seconds the request waits to be authorized; after that the page refuses it.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "request_id": {
            "description": "`creq_…`: names the request.",
            "type": "string"
          }
        },
        "required": [
          "request_id",
          "authorize_url",
          "expires_in_s"
        ],
        "type": "object"
      },
      "CliTokenCreate": {
        "additionalProperties": false,
        "description": "`POST /v1/auth/cli/token`: a command-line client exchanges the one-time code the signed-in person\nauthorized in the browser, with the PKCE verifier it kept, for an API key.",
        "properties": {
          "code": {
            "description": "The one-time code the authorize page handed the client (single use, five minutes).",
            "type": "string"
          },
          "code_verifier": {
            "description": "The PKCE verifier whose S256 challenge the client sent to the authorize page.",
            "type": "string"
          },
          "redirect_uri": {
            "description": "The loopback redirect the code was delivered to; absent for a code that was pasted.",
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "code",
          "code_verifier"
        ],
        "type": "object"
      },
      "Code": {
        "description": "Every error and failure code the API returns.",
        "oneOf": [
          {
            "enum": [
              "fork_failed",
              "start_timeout",
              "readiness_failed",
              "verify_too_slow",
              "verify_each_failed",
              "sandbox_unresponsive",
              "oom_within_tier",
              "disk_full_within_tier",
              "sandbox_interrupted",
              "integrity_mismatch",
              "egress_unavailable",
              "service_timeout",
              "capacity_busy",
              "verify_did_not_cover",
              "nonzero_exit",
              "task_timeout",
              "oom_over_tier",
              "disk_over_tier",
              "cap_killed",
              "cap_exceeded",
              "aborted_by_client",
              "expired",
              "not_started",
              "superseded",
              "usage",
              "internal",
              "auth",
              "not_found",
              "unreachable",
              "rate_limited",
              "timeout",
              "not_verified",
              "enoent",
              "trial_credits_exhausted",
              "card_required",
              "concurrency_limit",
              "egress_cap_reached",
              "network_policy_unsupported",
              "network_host_refused"
            ],
            "type": "string"
          },
          {
            "const": "toolchain_mismatch",
            "description": "A fixed toolchain command's output in the fork differs from what the verified snapshot\nrecorded.",
            "type": "string"
          },
          {
            "const": "resume_unavailable",
            "description": "The paused sandbox cannot be resumed right now. Nothing was started or billed, and it\nstays paused with its files.",
            "type": "string"
          },
          {
            "const": "sandbox_unreachable",
            "description": "The sandbox could not be reached just now. Nothing was changed or billed by this call.",
            "type": "string"
          },
          {
            "const": "region_at_capacity",
            "description": "Capacity is full right now, and waiting a moment may not be enough, unlike `capacity_busy`:\nretry later or ask for fewer at once. Env, unbilled, nothing started.",
            "type": "string"
          },
          {
            "const": "tier_unavailable",
            "description": "This tier cannot be started right now, and waiting will not help, unlike `capacity_busy`:\nuse a smaller tier, or ask support to enable it. Env, unbilled.",
            "type": "string"
          },
          {
            "const": "snapshot_unavailable",
            "description": "The snapshot could not be saved, so it can no longer be started: waiting will not help.\nTake a new snapshot or build it again. Env, unbilled, nothing started.",
            "type": "string"
          },
          {
            "const": "capacity_limit",
            "description": "More sandboxes of this size at once than one run can start at once: waiting will not\nhelp; fewer at once will. Env, unbilled, nothing started.",
            "type": "string"
          },
          {
            "const": "build_timeout",
            "description": "A snapshot build ran past its time limit on the builder; nothing was stored. The time it\nran is billed.",
            "type": "string"
          },
          {
            "const": "builder_unavailable",
            "description": "A new snapshot cannot be built at the moment. Unlike `capacity_busy` and `builder_busy`\nwaiting does not clear it; snapshots already built still run. Env, unbilled, nothing stored.",
            "type": "string"
          },
          {
            "const": "builder_busy",
            "description": "Other snapshot builds are ahead of this one. Unlike `builder_unavailable` this clears by\nwaiting: retry after `Retry-After`. Env, unbilled, nothing stored.",
            "type": "string"
          },
          {
            "const": "overloaded",
            "description": "The API is at capacity for a moment and did not start this request. Retry after\n`Retry-After`. Env, unbilled, nothing started.",
            "type": "string"
          },
          {
            "const": "preempted",
            "description": "A preemptible sandbox was stopped early, as preemptible runs can be. Its own outcome, not an\nenvironment failure: credited back (the time since its last snapshot, up to 24 hours), never\nauto-retried, replayable, and held out of the run's success rate rather than counted\nagainst it.",
            "type": "string"
          },
          {
            "const": "grader_failed",
            "description": "The grade could not be computed: the grader timed out, crashed, could not be placed in a\nclean fork, or printed something no `score` mode can read. The episode still bills; this\ndoes not.",
            "type": "string"
          },
          {
            "const": "grade_not_passed",
            "description": "The task's command completed and the grader judged its work a fail. Billed as the task's\noutcome; `exit_code` is the grader's.",
            "type": "string"
          },
          {
            "const": "shutdown_by_task",
            "description": "A command in the sandbox shut it down. Billed as the task's outcome.",
            "type": "string"
          },
          {
            "const": "modified_by_task",
            "description": "A file the verified snapshot provides was removed or changed inside the sandbox; the\nsnapshot's own copy is intact. Billed as the task's outcome.",
            "type": "string"
          },
          {
            "const": "cap_paused",
            "description": "The sandbox was paused when its run reached its spend cap. Its files and state are kept\nand paused time is not billed; it resumes once the cap is raised.",
            "type": "string"
          },
          {
            "const": "credits_paused",
            "description": "The sandbox was paused when the organization's credits ran out. Its files and state are\nkept and paused time is not billed; it resumes once credits are added.",
            "type": "string"
          },
          {
            "const": "stopped_by_support",
            "description": "Promigence support stopped the sandbox; `reason` says why. Billed for the seconds it ran,\nas a kill is, unless support found the cause was on our side; then that time is credited\nback.",
            "type": "string"
          },
          {
            "const": "forbidden",
            "description": "Authenticated, and a member of the organization, but the action needs the owner role. A\nnon-member gets `not_found` instead.",
            "type": "string"
          },
          {
            "const": "snapshot_incompatible",
            "description": "The snapshot can no longer run on the platform. Nothing was started or billed: rebuild it\nfrom the same source.",
            "type": "string"
          },
          {
            "const": "storage_limit_reached",
            "description": "Keeping this would take the organisation past its plan's storage limit. Nothing was stored\nor charged, and nothing already stored was removed.",
            "type": "string"
          },
          {
            "const": "dockerfile_build_failed",
            "description": "The customer gave us a Dockerfile and it did not build. Their input, not ours:\n400 / exit 2, nothing stored, the time the build ran billed, and the answer carries the\nlast lines of their own build output.",
            "type": "string"
          },
          {
            "const": "image_unresolvable",
            "description": "An `image` reference could not be turned into a digest because of the reference itself:\nno such tag, a malformed reference, credentials needed or refused, or no `linux/amd64`\nbuild. `{detail}` says which.",
            "type": "string"
          },
          {
            "const": "registry_unavailable",
            "description": "The image's registry could not be reached or did not answer usably while a tag was being\npinned. Not the image's fault: env, unbilled, nothing stored; retry after `Retry-After`.",
            "type": "string"
          },
          {
            "const": "credit_unclaimed",
            "description": "The account has free credit waiting that its owner has not claimed yet (claimed in the\nbrowser: `promigence credits claim`). Nothing was started or charged.",
            "type": "string"
          },
          {
            "const": "billing_unavailable",
            "description": "Card payments are not open yet, so no card can be added. Nothing was charged.",
            "type": "string"
          },
          {
            "const": "project_cap_reached",
            "description": "The work asked for would take its project past the monthly cap an owner set on it.",
            "type": "string"
          },
          {
            "const": "spend_limit_reached",
            "description": "The work asked for would take the org's card past its daily spend limit.",
            "type": "string"
          },
          {
            "const": "billing_hold",
            "description": "The organization takes no new work until a payment of its own that failed is paid, or while\none of its payments is disputed. Running sandboxes finish; nothing is suspended.",
            "type": "string"
          },
          {
            "const": "tier_over_plan",
            "description": "The tier's vCPUs are over the org's plan limit (`max_sandbox_vcpus` in `GET /v1/me`).",
            "type": "string"
          },
          {
            "const": "secrets_in_snapshot",
            "description": "A snapshot of a sandbox that was given the value of a secret, asked for without `force`:\nthe snapshot, and every sandbox started from it, could contain that value.",
            "type": "string"
          },
          {
            "const": "secrets_unavailable",
            "description": "Stored secrets cannot be used right now, so nothing that names one was started. Requests\nthat name no secret are unaffected. Env, unbilled.",
            "type": "string"
          },
          {
            "const": "secret_binding_unsupported",
            "description": "A secret bound to a host could not be set up for this sandbox, so it was discarded\nrather than started without it. Env, unbilled.",
            "type": "string"
          },
          {
            "const": "idempotency_key_reused",
            "description": "This `Idempotency-Key` was already used for a different request. Nothing was started.",
            "type": "string"
          },
          {
            "const": "idempotency_key_in_use",
            "description": "The first request with this `Idempotency-Key` is still running. Env, unbilled, nothing\nnew started: retry after `Retry-After` for its answer.",
            "type": "string"
          },
          {
            "const": "repo_credentials_not_supported",
            "description": "A repository URL carried a user name, password, token, query string or fragment. Nothing\nwas built or billed; private repositories are not supported yet.",
            "type": "string"
          },
          {
            "const": "account_exists",
            "description": "A first sign-in whose verified email address already has an account, through another\nsign-in method. Nothing was created: sign in with the method that account uses.",
            "type": "string"
          },
          {
            "const": "invite_invalid",
            "description": "An invite code that did not redeem: unknown, mistyped, expired, revoked or used up (one\nanswer for all of them). Nothing was created.",
            "type": "string"
          },
          {
            "const": "invite_required",
            "description": "A first sign-in while invite mode is on, with no redeemed invite code. Nothing was\ncreated: run `promigence signup` and enter the code.",
            "type": "string"
          },
          {
            "const": "key_expired",
            "description": "An API key past the expiry chosen when it was created. It no longer authenticates:\ncreate a new key.",
            "type": "string"
          },
          {
            "const": "account_blocked",
            "description": "The key's person is blocked: their own keys do not authenticate until it is reviewed.",
            "type": "string"
          },
          {
            "const": "setup_required",
            "description": "The account has setup questions to answer before new work starts. Nothing was started or\ncharged: answer them in the browser, then try again.",
            "type": "string"
          }
        ],
        "x-promigence-open-enum": true
      },
      "Concurrency": {
        "properties": {},
        "type": "object"
      },
      "ConnectRequest": {
        "description": "One request to connect a code host (`github` or `gitlab`) to the organization, started by the\nperson whose key or console session asked for it, and how it ended.",
        "properties": {
          "account": {
            "description": "The account on the code host, once it is known.",
            "type": [
              "string",
              "null"
            ]
          },
          "created_at": {
            "description": "RFC 3339.",
            "type": "string"
          },
          "finished_at": {
            "description": "RFC 3339: when it ended; absent while it is pending.",
            "type": [
              "string",
              "null"
            ]
          },
          "message": {
            "description": "One or two sentences for a person: what happened, then what to do next.",
            "type": "string"
          },
          "provider": {
            "description": "`github` or `gitlab`.",
            "type": "string"
          },
          "request_id": {
            "description": "`icr_` and 32 hex digits.",
            "type": "string"
          },
          "state": {
            "description": "`pending` while it is not finished; then how it ended: `connected`, `updated` (already\nconnected to this organization; its repository access changed), `already_connected`,\n`pending_provider_approval` (an owner of the account must approve it on the code host\nfirst), `declined`, `other_org` (connected to another organization), `needs_admin`,\n`not_installer`, `wrong_user` (the connection page was opened signed in to another\naccount), `expired` or `failed`.",
            "type": "string"
          }
        },
        "required": [
          "request_id",
          "provider",
          "state",
          "message",
          "created_at"
        ],
        "type": "object"
      },
      "ConnectTicket": {
        "description": "`POST /v1/integrations/{github,gitlab}/requests`: a connection started for you in the console.\nOpen `connect_url` in a browser signed in to the console as you, then read\n`GET /v1/integrations/{github,gitlab}/requests/{request_id}` for how it ends.",
        "properties": {
          "connect_url": {
            "description": "The console page that starts the connection: it carries the ticket and nothing else.",
            "type": "string"
          },
          "expires_at": {
            "description": "When the ticket stops working (RFC 3339): 5 minutes.",
            "type": "string"
          },
          "request_id": {
            "description": "The connection request it starts (`icr_` and 32 hex digits).",
            "type": "string"
          },
          "ticket_id": {
            "description": "`ict_` and 32 hex digits: used once, by you only, within 5 minutes.",
            "type": "string"
          }
        },
        "required": [
          "ticket_id",
          "request_id",
          "connect_url",
          "expires_at"
        ],
        "type": "object"
      },
      "Cost": {
        "properties": {
          "billable_seconds": {
            "default": 0,
            "description": "Σ `billable_seconds` over the run's sandboxes.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "cap_killed": {
            "type": "boolean"
          },
          "charged": {
            "format": "double",
            "type": "number"
          },
          "per_second_usd": {
            "default": 0,
            "format": "double",
            "type": "number"
          },
          "quoted": {
            "format": "double",
            "type": "number"
          },
          "unbilled": {
            "format": "double",
            "type": "number"
          }
        },
        "required": [
          "quoted",
          "charged",
          "unbilled",
          "cap_killed"
        ],
        "type": "object"
      },
      "CreditClaim": {
        "additionalProperties": false,
        "description": "`POST /v1/credits/claim`. Sent by the claim page.",
        "properties": {
          "accept_terms": {
            "type": "boolean"
          },
          "browser": {
            "type": [
              "string",
              "null"
            ]
          },
          "pow": {
            "type": [
              "string",
              "null"
            ]
          },
          "terms_version": {
            "type": [
              "string",
              "null"
            ]
          },
          "token": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "type": "object"
      },
      "CreditGrant": {
        "description": "A credit your organization received, and what is left of it.",
        "properties": {
          "expires_at": {
            "description": "When it expires, RFC 3339; `null` when it never expires.",
            "type": [
              "string",
              "null"
            ]
          },
          "granted_at": {
            "description": "When it was added, RFC 3339.",
            "type": "string"
          },
          "granted_usd": {
            "description": "USD.",
            "format": "double",
            "type": "number"
          },
          "kind": {
            "description": "What it is: `free_credit` (the free credit), `card_bonus` (credit for adding a card),\n`referral` (a referral reward), `plan` (usage included with a paid plan),\n`from_promigence` (credit Promigence added to your account), `service_restart` (credit\nfor a command a service restart stopped), `confirmation_credit` (a $1 charge that\nconfirmed a payment method, added back as credit), or `other`.",
            "type": "string"
          },
          "remaining_usd": {
            "description": "What is left of it, USD: 0 once it is used, expired or taken back. Credit that expires\nsoonest is used first, and credit that never expires last.",
            "format": "double",
            "type": "number"
          },
          "status": {
            "description": "`active` (some of it is left), `used` (all of it was used), `expired` (it expired before\nall of it was used), or `taken_back`.",
            "type": "string"
          }
        },
        "required": [
          "kind",
          "granted_usd",
          "remaining_usd",
          "granted_at",
          "status"
        ],
        "type": "object"
      },
      "CreditOffer": {
        "description": "The account's free credit (`GET /v1/credits/offer`, and the answer to a claim). The credit is\nclaimed in the browser, where the terms are accepted: `POST /v1/credits/claim-link` makes the\npage's link.",
        "properties": {
          "campaign": {
            "description": "The giveaway this credit comes from, when it does.",
            "type": [
              "string",
              "null"
            ]
          },
          "card_bonus_usd": {
            "description": "USD a first card would add, while it still would.",
            "format": "double",
            "type": "number"
          },
          "credit_usd": {
            "description": "USD: what a claim gives now (`claimable`) or gave (`claimed`).",
            "format": "double",
            "type": "number"
          },
          "expires_at": {
            "description": "When the credit expires (RFC 3339), when it does.",
            "type": [
              "string",
              "null"
            ]
          },
          "message": {
            "description": "One sentence for a person.",
            "type": "string"
          },
          "method_check_usd": {
            "default": 0,
            "description": "USD charged to confirm a payment method with no stable payer when it is added (Apple Pay,\nGoogle Pay, Amazon Pay): it is added to your credit, and the card bonus comes with it.",
            "format": "double",
            "type": "number"
          },
          "state": {
            "description": "`claimable`, `claimed`, `pending_review`, `needs_card`, `not_eligible`, `offer_ended`,\n`denied` or `none`.",
            "type": "string"
          }
        },
        "required": [
          "state",
          "credit_usd",
          "card_bonus_usd",
          "message"
        ],
        "type": "object"
      },
      "DirEntry": {
        "description": "One entry of a directory listing.",
        "properties": {
          "gid": {
            "default": null,
            "format": "uint32",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "is_dir": {
            "default": null,
            "type": [
              "boolean",
              "null"
            ]
          },
          "is_symlink": {
            "default": null,
            "type": [
              "boolean",
              "null"
            ]
          },
          "mode": {
            "default": null,
            "description": "Octal, with the file-type bits, like `FileInfo.mode`.",
            "type": [
              "string",
              "null"
            ]
          },
          "mtime_unix_ns": {
            "default": null,
            "format": "uint64",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "name": {
            "description": "The entry's own name, with no directory part.",
            "type": "string"
          },
          "path": {
            "description": "Absolute path inside the sandbox.",
            "type": "string"
          },
          "path_b64": {
            "description": "The exact bytes of `path`, base64, when the name is not UTF-8: `name` and `path` then show\nU+FFFD where those bytes are, and name no file. A directory holding such names is fetched\nexactly as an archive (`GET …/files/archive`).",
            "type": [
              "string",
              "null"
            ]
          },
          "size": {
            "default": null,
            "description": "`null` when the listing came from a fallback that could not report it — never `0`.",
            "format": "uint64",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "uid": {
            "default": null,
            "format": "uint32",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          }
        },
        "required": [
          "name",
          "path"
        ],
        "type": "object"
      },
      "DockerfileSource": {
        "additionalProperties": false,
        "description": "The Dockerfile form of a snapshot.",
        "properties": {
          "context": {
            "description": "The build context: `URL@<40-hex sha>` of a git repository, or a packed directory.",
            "type": "string"
          },
          "path": {
            "description": "The Dockerfile's path inside the context. Default `Dockerfile`.",
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "context"
        ],
        "type": "object"
      },
      "Egress": {
        "properties": {
          "bytes": {
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "host": {
            "type": "string"
          }
        },
        "required": [
          "host",
          "bytes"
        ],
        "type": "object"
      },
      "EgressCounters": {
        "description": "Data out for one sandbox.",
        "properties": {
          "bytes": {
            "description": "Bytes accounted so far.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "cut": {
            "description": "True once egress was cut because the organisation reached its monthly data-out cap.",
            "type": "boolean"
          }
        },
        "required": [
          "bytes",
          "cut"
        ],
        "type": "object"
      },
      "EgressUsage": {
        "description": "Data out in the period.",
        "properties": {
          "amount": {
            "description": "USD.",
            "format": "double",
            "type": "number"
          },
          "gib": {
            "format": "double",
            "type": "number"
          },
          "mib": {
            "format": "int64",
            "type": "integer"
          }
        },
        "required": [
          "mib",
          "gib",
          "amount"
        ],
        "type": "object"
      },
      "EpisodeUsage": {
        "description": "Per-episode charges from an older pricing model.",
        "properties": {
          "amount": {
            "description": "USD.",
            "format": "double",
            "type": "number"
          },
          "episodes": {
            "format": "int64",
            "type": "integer"
          }
        },
        "required": [
          "episodes",
          "amount"
        ],
        "type": "object"
      },
      "ExecCreate": {
        "additionalProperties": false,
        "description": "`POST /v1/sandboxes/{id}/execs`, and the `exec` of `POST /v1/runs`: one command. `argv` (a\nnon-empty list) or `sh` (a shell line) is required.",
        "properties": {
          "argv": {
            "description": "The program and its arguments, run without a shell.",
            "items": {
              "type": "string"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "background": {
            "description": "Answer at once (202) with a handle to poll, instead of waiting for the command.",
            "type": "boolean"
          },
          "cwd": {
            "description": "The working directory. Defaults to the snapshot's workspace.",
            "type": [
              "string",
              "null"
            ]
          },
          "encoding": {
            "description": "`text` (the default) or `base64`: the answer's output as `stdout_b64` / `stderr_b64`, the\nexact bytes, for output that is not text (an archive, an image). The buffered answer only.",
            "type": [
              "string",
              "null"
            ]
          },
          "env": {
            "additionalProperties": {
              "type": "string"
            },
            "description": "Extra environment variables.",
            "type": "object"
          },
          "follow": {
            "description": "With `background`: the command is read as it runs, by a caller that may lose its\nconnection and come back. The newest `max_output_bytes` of each stream are kept (8 MiB by\ndefault; older bytes are dropped, and a read that asks for them says how many in\n`skipped`), and the handle is freed 10 minutes after the command ends, read or not. The\ncommand never stops because a caller went away.",
            "type": "boolean"
          },
          "kill_on_exit": {
            "description": "End the sandbox when the command exits (default: the value of `terminal`).",
            "type": [
              "boolean",
              "null"
            ]
          },
          "max_output_bytes": {
            "description": "Output kept per stream, in bytes (default 64 KiB, 1 MiB for a background exec; max 32 MiB).",
            "format": "uint64",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "secrets": {
            "description": "Stored secrets the command receives as environment variables.",
            "items": {
              "$ref": "#/components/schemas/SecretUse"
            },
            "type": "array"
          },
          "sh": {
            "description": "A line for `sh -c`.",
            "type": [
              "string",
              "null"
            ]
          },
          "stdin": {
            "description": "Keep the command's stdin open for `POST …/execs/{exec_id}/stdin` (background execs).",
            "type": "boolean"
          },
          "terminal": {
            "description": "The sandbox ends when this command exits.",
            "type": "boolean"
          },
          "timeout_ms": {
            "description": "Milliseconds before the command is ended. A positive integer; omitted, 15 minutes.",
            "format": "uint64",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "user": {
            "description": "The user to run as.",
            "type": [
              "string",
              "null"
            ]
          }
        },
        "type": "object"
      },
      "ExecForgotten": {
        "description": "`DELETE /v1/sandboxes/{id}/execs/{exec_id}` — the handle and its buffered output are gone.",
        "properties": {
          "exec_id": {
            "type": "string"
          },
          "forgotten": {
            "type": "boolean"
          },
          "ok": {
            "type": "boolean"
          },
          "sandbox_id": {
            "type": "string"
          }
        },
        "required": [
          "ok",
          "sandbox_id",
          "exec_id",
          "forgotten"
        ],
        "type": "object"
      },
      "ExecRecord": {
        "properties": {
          "argv": {
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "cpu_ms": {
            "format": "double",
            "type": "number"
          },
          "cwd": {
            "type": [
              "string",
              "null"
            ]
          },
          "env_keys": {
            "default": [],
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "exec_id": {
            "type": "string"
          },
          "exit_code": {
            "format": "int32",
            "type": [
              "integer",
              "null"
            ]
          },
          "max_rss_kib": {
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "signal": {
            "format": "int32",
            "type": [
              "integer",
              "null"
            ]
          },
          "started_at": {
            "type": "string"
          },
          "stderr_ref": {
            "type": [
              "string",
              "null"
            ]
          },
          "stdout_ref": {
            "type": [
              "string",
              "null"
            ]
          },
          "truncated": {
            "type": "boolean"
          },
          "wall_ms": {
            "format": "double",
            "type": "number"
          }
        },
        "required": [
          "exec_id",
          "argv",
          "started_at",
          "wall_ms",
          "cpu_ms",
          "max_rss_kib",
          "truncated"
        ],
        "type": "object"
      },
      "ExecResult": {
        "description": "`POST /v1/sandboxes/{id}/execs` — a buffered command that has finished.\n\nThis is the `application/json` answer. `Accept: text/event-stream` streams the same command\ninstead, and `background: true` answers `202` with a [`BackgroundExec`] to poll.",
        "properties": {
          "cpu_ms": {
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "exec_id": {
            "type": "string"
          },
          "exit_code": {
            "description": "`null` if a signal killed the command.",
            "format": "int32",
            "type": [
              "integer",
              "null"
            ]
          },
          "oom_killed": {
            "description": "Present (true) when the command was killed for running out of memory.",
            "type": "boolean"
          },
          "reason": {
            "description": "Why the command ended without an exit code: `timeout`, `out_of_memory` or `signal`.\nAbsent when it exited on its own.",
            "type": [
              "string",
              "null"
            ]
          },
          "sandbox_id": {
            "type": "string"
          },
          "signal": {
            "description": "The signal that killed it, if one did.",
            "format": "int32",
            "type": [
              "integer",
              "null"
            ]
          },
          "stderr": {
            "type": [
              "string",
              "null"
            ]
          },
          "stderr_b64": {
            "description": "With `encoding: \"base64\"`: the exact bytes of standard error, base64.",
            "type": [
              "string",
              "null"
            ]
          },
          "stdout": {
            "type": [
              "string",
              "null"
            ]
          },
          "stdout_b64": {
            "description": "With `encoding: \"base64\"`: the exact bytes of standard output, base64 (`stdout` is then\nempty). Bytes that are not UTF-8 survive here; as text they become U+FFFD.",
            "type": [
              "string",
              "null"
            ]
          },
          "timed_out": {
            "description": "Present (true) when the command was killed at its own `timeout_ms`.",
            "type": "boolean"
          },
          "truncated": {
            "description": "True when the output was cut at the request's byte limit.",
            "type": "boolean"
          },
          "wall_ms": {
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          }
        },
        "required": [
          "exec_id",
          "sandbox_id",
          "truncated"
        ],
        "type": "object"
      },
      "ExecSignal": {
        "additionalProperties": false,
        "description": "`POST /v1/sandboxes/{id}/execs/{exec_id}/signal`.",
        "properties": {
          "signal": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/NumberOrName"
              },
              {
                "type": "null"
              }
            ],
            "description": "A signal number 1–64, or a name such as `SIGTERM` or `TERM`. Default 15 (SIGTERM)."
          }
        },
        "type": "object"
      },
      "ExecSignalled": {
        "description": "`POST /v1/sandboxes/{id}/execs/{exec_id}/signal`.",
        "properties": {
          "already_ended": {
            "description": "Present, and true, only when the command had already finished.",
            "type": [
              "boolean",
              "null"
            ]
          },
          "delivered": {
            "description": "False when the command had already finished, which is not a failure: the process is\ngone, which is what a kill wanted.",
            "type": "boolean"
          },
          "exec_id": {
            "type": "string"
          },
          "ok": {
            "type": "boolean"
          },
          "sandbox_id": {
            "type": "string"
          },
          "signal": {
            "description": "The signal that was sent, as a number.",
            "format": "int32",
            "type": "integer"
          }
        },
        "required": [
          "ok",
          "sandbox_id",
          "exec_id",
          "signal",
          "delivered"
        ],
        "type": "object"
      },
      "ExecStdin": {
        "additionalProperties": false,
        "description": "`POST /v1/sandboxes/{id}/execs/{exec_id}/stdin`: `data`, `eof`, or both.",
        "properties": {
          "data": {
            "description": "Bytes to write, base64.",
            "type": [
              "string",
              "null"
            ]
          },
          "eof": {
            "description": "Close stdin after this write.",
            "type": "boolean"
          }
        },
        "type": "object"
      },
      "ExecView": {
        "description": "One command that ran in a sandbox, with its recorded output.",
        "properties": {
          "argv": {
            "description": "The command, as it was run.",
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "cpu_ms": {
            "format": "double",
            "type": "number"
          },
          "cwd": {
            "description": "The working directory it ran in.",
            "type": [
              "string",
              "null"
            ]
          },
          "env_keys": {
            "description": "The names of the environment variables it was given. Never the values.",
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "exec_id": {
            "type": "string"
          },
          "exit_code": {
            "description": "`null` while it is still running, or if a signal killed it.",
            "format": "int32",
            "type": [
              "integer",
              "null"
            ]
          },
          "max_rss_kib": {
            "description": "Peak resident memory, in kibibytes.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "run_id": {
            "type": "string"
          },
          "sandbox_id": {
            "type": "string"
          },
          "signal": {
            "description": "The signal that killed it, if one did.",
            "format": "int32",
            "type": [
              "integer",
              "null"
            ]
          },
          "started_at": {
            "description": "When it started, RFC 3339.",
            "type": "string"
          },
          "stderr": {
            "type": "string"
          },
          "stdout": {
            "type": "string"
          },
          "terminal": {
            "description": "True when this command owned the sandbox: the sandbox ends when the command does.",
            "type": "boolean"
          },
          "truncated": {
            "description": "True when the output was cut: at the request's byte limit, or, in a sandbox's `execs`, to\nthe last 64 KiB of each stream. `GET /v1/execs/{id}` returns the whole recorded output.",
            "type": "boolean"
          },
          "wall_ms": {
            "format": "double",
            "type": "number"
          }
        },
        "required": [
          "exec_id",
          "sandbox_id",
          "run_id",
          "argv",
          "env_keys",
          "started_at",
          "wall_ms",
          "cpu_ms",
          "max_rss_kib",
          "stdout",
          "stderr",
          "truncated",
          "terminal"
        ],
        "type": "object"
      },
      "ExpiringCredit": {
        "description": "A credit grant that expires.",
        "properties": {
          "expires_at": {
            "description": "RFC 3339.",
            "type": "string"
          },
          "granted_usd": {
            "format": "double",
            "type": "number"
          },
          "remaining_usd": {
            "description": "What is left of it, USD (credit that expires soonest is used first).",
            "format": "double",
            "type": "number"
          }
        },
        "required": [
          "remaining_usd",
          "granted_usd",
          "expires_at"
        ],
        "type": "object"
      },
      "ExtensionCost": {
        "description": "What an extension does to the run's budget, in USD.",
        "properties": {
          "added": {
            "description": "What the extra seconds cost.",
            "format": "double",
            "type": "number"
          },
          "ceiling": {
            "description": "The run's ceiling: the lower of its quote and its spend cap.",
            "format": "double",
            "type": "number"
          },
          "charged": {
            "description": "Already charged for this run.",
            "format": "double",
            "type": "number"
          },
          "live_commitment": {
            "description": "Committed to this run's live sandboxes, this extension included.",
            "format": "double",
            "type": "number"
          },
          "remaining": {
            "description": "What is left of the ceiling once this extension is paid for.",
            "format": "double",
            "type": "number"
          }
        },
        "required": [
          "added",
          "charged",
          "live_commitment",
          "ceiling",
          "remaining"
        ],
        "type": "object"
      },
      "ExtractResult": {
        "description": "The reply to `POST /v1/sandboxes/:id/files/extract`.",
        "properties": {
          "archive": {
            "type": "string"
          },
          "entries": {
            "default": null,
            "description": "Entries written. `null` from the fallback path, which cannot count them without a second\npass over the archive — and a number nobody counted is worse than no number.",
            "format": "uint64",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "into": {
            "type": "string"
          },
          "sandbox_id": {
            "type": "string"
          },
          "served_by": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "sandbox_id",
          "archive",
          "into"
        ],
        "type": "object"
      },
      "Failure": {
        "properties": {
          "category": {
            "$ref": "#/components/schemas/FailureCategory"
          },
          "code": {
            "$ref": "#/components/schemas/Code"
          },
          "evidence": {
            "additionalProperties": {},
            "default": {},
            "type": "object"
          }
        },
        "required": [
          "category",
          "code"
        ],
        "type": "object"
      },
      "FailureCategory": {
        "oneOf": [
          {
            "enum": [
              "env",
              "snapshot",
              "task",
              "cap"
            ],
            "type": "string"
          },
          {
            "const": "grader",
            "description": "The grader itself broke — it timed out, crashed, or emitted unparseable output. Never the\ncustomer's task failing, exactly as `Env` is not.",
            "type": "string"
          },
          {
            "const": "preempt",
            "description": "A preemptible sandbox was stopped early, as preemptible runs can be. **Not `Env`**: an\nenvironment failure is something that broke, a preemption is what the customer opted into\nand pays less for, and filing one under the other corrupts the env-vs-task attribution the\nvalidity report exists to produce.",
            "type": "string"
          },
          {
            "const": "other",
            "description": "`aborted_by_client`, `stopped_by_support`, `expired`, `not_started`, `superseded` and the\nAPI/CLI errors.",
            "type": "string"
          }
        ],
        "x-promigence-open-enum": true
      },
      "FileArchive": {
        "additionalProperties": false,
        "description": "`POST /v1/sandboxes/{id}/files/archive`: pack a path into a `.tar.gz` inside the sandbox.",
        "properties": {
          "exclude": {
            "description": "Name globs left out, e.g. `[\".git\"]`.",
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "out": {
            "description": "Where the archive is written (absolute). Default: beside the source.",
            "type": [
              "string",
              "null"
            ]
          },
          "path": {
            "type": "string"
          }
        },
        "required": [
          "path"
        ],
        "type": "object"
      },
      "FileChmod": {
        "additionalProperties": false,
        "description": "`POST /v1/sandboxes/{id}/files/chmod`: at least one of `mode`, `uid`, `gid`.",
        "properties": {
          "gid": {
            "format": "uint32",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "mode": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/FileMode"
              },
              {
                "type": "null"
              }
            ]
          },
          "path": {
            "type": "string"
          },
          "recursive": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "uid": {
            "format": "uint32",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          }
        },
        "required": [
          "path"
        ],
        "type": "object"
      },
      "FileCopy": {
        "additionalProperties": false,
        "description": "`POST /v1/sandboxes/{id}/files/copy`.",
        "properties": {
          "from": {
            "type": "string"
          },
          "overwrite": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "recursive": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "to": {
            "type": "string"
          }
        },
        "required": [
          "from",
          "to"
        ],
        "type": "object"
      },
      "FileDeleted": {
        "description": "`DELETE /v1/sandboxes/{id}/files`. Idempotent: a path that was not there is a 200 with\n`existed: false`, not a 404.",
        "properties": {
          "deleted": {
            "type": "boolean"
          },
          "existed": {
            "description": "False when there was nothing at that path to begin with.",
            "type": "boolean"
          },
          "ok": {
            "type": "boolean"
          },
          "path": {
            "type": "string"
          },
          "sandbox_id": {
            "type": "string"
          }
        },
        "required": [
          "ok",
          "sandbox_id",
          "path",
          "deleted",
          "existed"
        ],
        "type": "object"
      },
      "FileExtract": {
        "additionalProperties": false,
        "description": "`POST /v1/sandboxes/{id}/files/extract`.",
        "properties": {
          "archive": {
            "type": "string"
          },
          "into": {
            "type": "string"
          },
          "strip": {
            "description": "Leading path components dropped from each entry, 0–32.",
            "format": "uint32",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          }
        },
        "required": [
          "archive",
          "into"
        ],
        "type": "object"
      },
      "FileInfo": {
        "description": "The reply to `mkdir`, `move`, `copy` and `chmod`: the path as it now is.\n\n`mode` is a **string of octal** and carries the file-type bits (`\"40755\"` is a directory).\nIt is a string because a JSON number cannot be written `0755`, and every consumer of a mode\nwants it in base 8; it carries the type bits because that is what `GET /files/stat` has\nalways returned and two spellings of one field is how a client ends up with a bug.",
        "properties": {
          "is_dir": {
            "type": "boolean"
          },
          "is_symlink": {
            "type": "boolean"
          },
          "mode": {
            "type": "string"
          },
          "mtime_unix_ns": {
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "path": {
            "type": "string"
          },
          "sandbox_id": {
            "type": "string"
          },
          "served_by": {
            "type": [
              "string",
              "null"
            ]
          },
          "size": {
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "sandbox_id",
          "path",
          "size",
          "mode",
          "mtime_unix_ns",
          "is_dir",
          "is_symlink"
        ],
        "type": "object"
      },
      "FileListing": {
        "description": "The reply to `GET /v1/sandboxes/:id/files/list`.",
        "properties": {
          "entries": {
            "items": {
              "$ref": "#/components/schemas/DirEntry"
            },
            "type": "array"
          },
          "path": {
            "type": "string"
          },
          "sandbox_id": {
            "type": "string"
          },
          "served_by": {
            "type": [
              "string",
              "null"
            ]
          },
          "truncated": {
            "description": "The listing stopped at `limit`. **Not** \"the directory ended\" — a caller that treats a\ntruncated page as a complete one will report a file as missing when it is merely past\nthe cut.",
            "type": "boolean"
          }
        },
        "required": [
          "sandbox_id",
          "path",
          "entries",
          "truncated"
        ],
        "type": "object"
      },
      "FileMkdir": {
        "additionalProperties": false,
        "description": "`POST /v1/sandboxes/{id}/files/mkdir`. Paths are absolute.",
        "properties": {
          "mode": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/FileMode"
              },
              {
                "type": "null"
              }
            ]
          },
          "parents": {
            "description": "Create missing parents too.",
            "type": [
              "boolean",
              "null"
            ]
          },
          "path": {
            "type": "string"
          }
        },
        "required": [
          "path"
        ],
        "type": "object"
      },
      "FileMode": {
        "anyOf": [
          {
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          {
            "type": "string"
          }
        ],
        "description": "A permission mode: a number, or an octal string such as `\"755\"`."
      },
      "FileMove": {
        "additionalProperties": false,
        "description": "`POST /v1/sandboxes/{id}/files/move`.",
        "properties": {
          "from": {
            "type": "string"
          },
          "overwrite": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "to": {
            "type": "string"
          }
        },
        "required": [
          "from",
          "to"
        ],
        "type": "object"
      },
      "FileStat": {
        "description": "Size, mode, modification time and kind for one path, as the sandbox reports them.\n\nEvery field is optional because the answer is the sandbox's, not ours: a path the sandbox\ncould not describe comes back named but otherwise empty, rather than filled in with zeroes.",
        "properties": {
          "is_dir": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "is_symlink": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "mode": {
            "description": "The permission bits, octal, without a leading zero (`644`).",
            "type": [
              "string",
              "null"
            ]
          },
          "mtime_unix_ns": {
            "format": "uint64",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "path": {
            "type": [
              "string",
              "null"
            ]
          },
          "size": {
            "description": "Bytes.",
            "format": "uint64",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          }
        },
        "type": "object"
      },
      "FileStatView": {
        "description": "`GET /v1/sandboxes/{id}/files/stat`.",
        "properties": {
          "path": {
            "type": "string"
          },
          "sandbox_id": {
            "type": "string"
          },
          "stat": {
            "$ref": "#/components/schemas/FileStat"
          }
        },
        "required": [
          "sandbox_id",
          "path",
          "stat"
        ],
        "type": "object"
      },
      "FileWritten": {
        "description": "The answer to `PUT /v1/sandboxes/{id}/files` (the request body is the file's bytes).",
        "properties": {
          "bytes": {
            "description": "Bytes written by this request.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "chunks": {
            "description": "How many pieces the write was sent in.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "mode": {
            "description": "The file's permission bits after the write, octal (`644`). Without `?mode=` a file that\nalready existed keeps its own, and a new file is `644`.",
            "type": "string"
          },
          "offset": {
            "description": "Where this request's bytes start in the file (`?offset=`, else 0).",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "ok": {
            "type": "boolean"
          },
          "path": {
            "type": "string"
          },
          "sandbox_id": {
            "type": "string"
          },
          "stat": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/FileStat"
              },
              {
                "type": "null"
              }
            ],
            "description": "The file as the sandbox describes it after the write; `null` when it could not say."
          }
        },
        "required": [
          "ok",
          "sandbox_id",
          "path",
          "bytes",
          "chunks",
          "mode",
          "offset"
        ],
        "type": "object"
      },
      "ForkStats": {
        "properties": {
          "e2e_ms": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Percentiles"
              },
              {
                "type": "null"
              }
            ]
          },
          "final_success_pct": {
            "format": "double",
            "type": "number"
          },
          "first_attempt_success_pct": {
            "format": "double",
            "type": "number"
          },
          "n": {
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "percentile_method": {
            "type": "string"
          },
          "queued_ms": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Percentiles"
              },
              {
                "type": "null"
              }
            ]
          },
          "ready_ms": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Percentiles"
              },
              {
                "type": "null"
              }
            ]
          },
          "replay": {
            "$ref": "#/components/schemas/ReplayStats"
          },
          "verify_each_ms": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Percentiles"
              },
              {
                "type": "null"
              }
            ]
          },
          "warm_retries": {
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "n",
          "warm_retries",
          "first_attempt_success_pct",
          "final_success_pct",
          "percentile_method",
          "replay"
        ],
        "type": "object"
      },
      "GithubConnect": {
        "description": "`POST /v1/integrations/github/connect`: where to install the App. Open `install_url` in a\nbrowser; GitHub sends it back to us when the install is done, and `GET\n/v1/integrations/github` then lists the connection.",
        "properties": {
          "app_slug": {
            "description": "The App's name on GitHub (`github.com/apps/<slug>`).",
            "type": "string"
          },
          "expires_at": {
            "description": "When the link stops working (RFC 3339): 15 minutes.",
            "type": "string"
          },
          "install_url": {
            "description": "GitHub's install page for the App, carrying a signed state that names this organization.",
            "type": "string"
          }
        },
        "required": [
          "install_url",
          "expires_at",
          "app_slug"
        ],
        "type": "object"
      },
      "GithubConnection": {
        "description": "One GitHub account (a user or an organization) whose App installation is connected.",
        "properties": {
          "account": {
            "description": "The GitHub account's login.",
            "type": "string"
          },
          "account_type": {
            "description": "`User` or `Organization`.",
            "type": "string"
          },
          "connected_at": {
            "description": "RFC 3339.",
            "type": "string"
          },
          "installation_id": {
            "description": "GitHub's id of the installation. What `github disconnect` takes.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "manage_url": {
            "description": "Where the account changes which repositories the App can read, or uninstalls it.",
            "type": "string"
          },
          "repository_selection": {
            "description": "`all` (every repository of the account) or `selected` (the ones chosen at install).",
            "type": "string"
          },
          "suspended": {
            "description": "The installation is suspended on GitHub: nothing is built from it until it is unsuspended.",
            "type": "boolean"
          }
        },
        "required": [
          "installation_id",
          "account",
          "account_type",
          "repository_selection",
          "suspended",
          "connected_at",
          "manage_url"
        ],
        "type": "object"
      },
      "GithubDisconnected": {
        "description": "`DELETE /v1/integrations/github/installations/{installation_id}`.",
        "properties": {
          "account": {
            "type": "string"
          },
          "disconnected": {
            "description": "Always true here.",
            "type": "boolean"
          },
          "installation_id": {
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "message": {
            "type": "string"
          },
          "tracks_removed": {
            "description": "Snapshots that followed a branch of this account, and follow nothing now.",
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "uninstall_url": {
            "description": "The App stays installed on the GitHub account until it is uninstalled there.",
            "type": "string"
          }
        },
        "required": [
          "installation_id",
          "account",
          "disconnected",
          "tracks_removed",
          "uninstall_url",
          "message"
        ],
        "type": "object"
      },
      "GithubPending": {
        "description": "A connection that is not finished: the install came back to us, and GitHub's own\nnotification of it has not (it usually follows within seconds).",
        "properties": {
          "account": {
            "description": "The GitHub account's login, when known.",
            "type": [
              "string",
              "null"
            ]
          },
          "claimed_at": {
            "description": "RFC 3339.",
            "type": "string"
          },
          "installation_id": {
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "message": {
            "description": "One sentence for a person.",
            "type": "string"
          },
          "state": {
            "description": "`waiting_for_github` or `conflict`.",
            "type": "string"
          }
        },
        "required": [
          "installation_id",
          "claimed_at",
          "state",
          "message"
        ],
        "type": "object"
      },
      "GithubRepo": {
        "description": "One repository the organization's connections can read.",
        "properties": {
          "account": {
            "description": "The GitHub account the repository belongs to.",
            "type": "string"
          },
          "archived": {
            "type": "boolean"
          },
          "default_branch": {
            "type": "string"
          },
          "full_name": {
            "description": "`owner/name`: what `snapshot create --repo` takes.",
            "type": "string"
          },
          "installation_id": {
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "private": {
            "type": "boolean"
          },
          "pushed_at": {
            "description": "RFC 3339, when GitHub says.",
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "full_name",
          "private",
          "default_branch",
          "installation_id",
          "account",
          "archived"
        ],
        "type": "object"
      },
      "GithubRepos": {
        "description": "`GET /v1/integrations/github/repos`: one page of repositories, across every connection.",
        "properties": {
          "has_more": {
            "type": "boolean"
          },
          "page": {
            "description": "1-based.",
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "per_page": {
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "repos": {
            "items": {
              "$ref": "#/components/schemas/GithubRepo"
            },
            "type": "array"
          },
          "total": {
            "description": "Repositories across every connection.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "repos",
          "page",
          "per_page",
          "total",
          "has_more"
        ],
        "type": "object"
      },
      "GithubStatus": {
        "description": "`GET /v1/integrations/github`: the organization's GitHub connections, the ones still being\nfinished, and the snapshots that follow a branch.",
        "properties": {
          "app_slug": {
            "type": [
              "string",
              "null"
            ]
          },
          "configured": {
            "description": "False when GitHub connections are not available: nothing here works then, and `message` says so.",
            "type": "boolean"
          },
          "connections": {
            "items": {
              "$ref": "#/components/schemas/GithubConnection"
            },
            "type": "array"
          },
          "message": {
            "type": [
              "string",
              "null"
            ]
          },
          "pending": {
            "items": {
              "$ref": "#/components/schemas/GithubPending"
            },
            "type": "array"
          },
          "tracks": {
            "items": {
              "$ref": "#/components/schemas/GithubTrack"
            },
            "type": "array"
          }
        },
        "required": [
          "configured",
          "connections",
          "pending",
          "tracks"
        ],
        "type": "object"
      },
      "GithubTrack": {
        "description": "A snapshot that follows a branch: every push to it builds the snapshot again (each automatic\nbuild is a normal build, charged to the organization).",
        "properties": {
          "alias": {
            "description": "The alias the newest build of the branch carries.",
            "type": "string"
          },
          "branch": {
            "type": "string"
          },
          "build_id": {
            "description": "The build in progress for this branch, when there is one.",
            "type": [
              "string",
              "null"
            ]
          },
          "built_sha": {
            "description": "The commit the snapshot named by `alias` was built from.",
            "type": [
              "string",
              "null"
            ]
          },
          "created_at": {
            "description": "RFC 3339.",
            "type": "string"
          },
          "head_sha": {
            "description": "The newest commit pushed to the branch, when one was.",
            "type": [
              "string",
              "null"
            ]
          },
          "last_error": {
            "description": "Why the last automatic build did not start or did not finish, when it did not.",
            "type": [
              "string",
              "null"
            ]
          },
          "repo": {
            "description": "`owner/name`.",
            "type": "string"
          },
          "snapshot_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "track_id": {
            "type": "string"
          }
        },
        "required": [
          "track_id",
          "repo",
          "branch",
          "alias",
          "created_at"
        ],
        "type": "object"
      },
      "GithubUntracked": {
        "description": "`DELETE /v1/integrations/github/tracks/{track_id}`: the snapshot stays; pushes no longer\nrebuild it.",
        "properties": {
          "alias": {
            "type": "string"
          },
          "branch": {
            "type": "string"
          },
          "repo": {
            "type": "string"
          },
          "track_id": {
            "type": "string"
          },
          "untracked": {
            "description": "Always true here.",
            "type": "boolean"
          }
        },
        "required": [
          "track_id",
          "repo",
          "branch",
          "alias",
          "untracked"
        ],
        "type": "object"
      },
      "GitlabConnect": {
        "description": "`POST /v1/integrations/gitlab/connect`: where to authorize the application. Open\n`authorize_url` in a browser; once you have approved it there and an owner of the organization\nhas confirmed it, `GET /v1/integrations/gitlab` lists the connection.",
        "properties": {
          "authorize_url": {
            "description": "GitLab's authorization page, carrying a signed state that names this organization.",
            "type": "string"
          },
          "expires_at": {
            "description": "When the link stops working (RFC 3339): 15 minutes.",
            "type": "string"
          },
          "gitlab_url": {
            "description": "The GitLab the connection is made on (`https://gitlab.com`).",
            "type": "string"
          },
          "scopes": {
            "description": "What the application asks for: read-only access.",
            "items": {
              "type": "string"
            },
            "type": "array"
          }
        },
        "required": [
          "authorize_url",
          "expires_at",
          "gitlab_url",
          "scopes"
        ],
        "type": "object"
      },
      "GitlabConnection": {
        "description": "One GitLab user whose read-only authorization is connected to the organization.",
        "properties": {
          "broken": {
            "description": "The authorization stopped working (revoked on GitLab, or expired): nothing is built from\nit until it is connected again. `broken_reason` says why.",
            "type": "boolean"
          },
          "broken_reason": {
            "type": [
              "string",
              "null"
            ]
          },
          "connected_at": {
            "description": "RFC 3339.",
            "type": "string"
          },
          "connection_id": {
            "description": "What `gitlab disconnect` takes.",
            "type": "string"
          },
          "gitlab_url": {
            "type": "string"
          },
          "user_id": {
            "description": "GitLab's numeric id of that user.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "username": {
            "description": "The GitLab username.",
            "type": "string"
          },
          "webhook_token": {
            "description": "The webhook's secret token. It can only make us look at your tracked branches sooner.",
            "type": "string"
          },
          "webhook_url": {
            "description": "Optional: a project webhook for instant rebuilds of tracked branches (otherwise a tracked\nbranch is checked every minute). Add it in GitLab under Settings > Webhooks, push events.",
            "type": "string"
          }
        },
        "required": [
          "connection_id",
          "username",
          "user_id",
          "gitlab_url",
          "connected_at",
          "broken",
          "webhook_url",
          "webhook_token"
        ],
        "type": "object"
      },
      "GitlabDisconnected": {
        "description": "`DELETE /v1/integrations/gitlab/connections/{connection_id}`.",
        "properties": {
          "connection_id": {
            "type": "string"
          },
          "disconnected": {
            "description": "Always true here.",
            "type": "boolean"
          },
          "message": {
            "type": "string"
          },
          "revoked": {
            "description": "Our token was revoked on GitLab. False when GitLab did not answer: then remove the\napplication under your GitLab user settings > Applications.",
            "type": "boolean"
          },
          "tracks_removed": {
            "description": "Snapshots that followed a branch through this connection, and follow nothing now.",
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "username": {
            "type": "string"
          }
        },
        "required": [
          "connection_id",
          "username",
          "disconnected",
          "revoked",
          "tracks_removed",
          "message"
        ],
        "type": "object"
      },
      "GitlabPending": {
        "description": "An authorization waiting for an owner of the organization to confirm it in the browser that\nmade it.",
        "properties": {
          "authorized_at": {
            "description": "RFC 3339.",
            "type": "string"
          },
          "connection_id": {
            "type": "string"
          },
          "expires_at": {
            "description": "RFC 3339: after it, the authorization is dropped and its token revoked.",
            "type": "string"
          },
          "message": {
            "description": "One sentence for a person.",
            "type": "string"
          },
          "username": {
            "type": "string"
          }
        },
        "required": [
          "connection_id",
          "username",
          "authorized_at",
          "expires_at",
          "message"
        ],
        "type": "object"
      },
      "GitlabRepo": {
        "description": "One GitLab project the organization's connections can read.",
        "properties": {
          "archived": {
            "type": "boolean"
          },
          "connection_id": {
            "type": "string"
          },
          "default_branch": {
            "type": "string"
          },
          "last_activity_at": {
            "description": "RFC 3339, when GitLab says.",
            "type": [
              "string",
              "null"
            ]
          },
          "path": {
            "description": "`group/sub/project`: what `snapshot create --repo gitlab:<path>` takes.",
            "type": "string"
          },
          "private": {
            "type": "boolean"
          },
          "project_id": {
            "description": "GitLab's numeric project id.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "path",
          "project_id",
          "private",
          "default_branch",
          "archived",
          "connection_id"
        ],
        "type": "object"
      },
      "GitlabRepos": {
        "description": "`GET /v1/integrations/gitlab/repos`: one page of projects, across every connection.",
        "properties": {
          "has_more": {
            "type": "boolean"
          },
          "page": {
            "description": "1-based.",
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "per_page": {
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "repos": {
            "items": {
              "$ref": "#/components/schemas/GitlabRepo"
            },
            "type": "array"
          }
        },
        "required": [
          "repos",
          "page",
          "per_page",
          "has_more"
        ],
        "type": "object"
      },
      "GitlabStatus": {
        "description": "`GET /v1/integrations/gitlab`.",
        "properties": {
          "configured": {
            "description": "False on a deployment with no GitLab application: nothing here works there, and `message`\nsays so.",
            "type": "boolean"
          },
          "connections": {
            "items": {
              "$ref": "#/components/schemas/GitlabConnection"
            },
            "type": "array"
          },
          "gitlab_url": {
            "type": [
              "string",
              "null"
            ]
          },
          "message": {
            "type": [
              "string",
              "null"
            ]
          },
          "pending": {
            "items": {
              "$ref": "#/components/schemas/GitlabPending"
            },
            "type": "array"
          },
          "tracks": {
            "items": {
              "$ref": "#/components/schemas/GitlabTrack"
            },
            "type": "array"
          }
        },
        "required": [
          "configured",
          "connections",
          "pending",
          "tracks"
        ],
        "type": "object"
      },
      "GitlabTrack": {
        "description": "A snapshot that follows a GitLab branch: every new commit on it builds the snapshot again\n(each automatic build is a normal build, charged to the organization).",
        "properties": {
          "alias": {
            "description": "The alias the newest build of the branch carries.",
            "type": "string"
          },
          "branch": {
            "type": "string"
          },
          "build_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "built_sha": {
            "type": [
              "string",
              "null"
            ]
          },
          "created_at": {
            "description": "RFC 3339.",
            "type": "string"
          },
          "head_sha": {
            "type": [
              "string",
              "null"
            ]
          },
          "last_error": {
            "type": [
              "string",
              "null"
            ]
          },
          "repo": {
            "description": "The project's path (`group/sub/project`).",
            "type": "string"
          },
          "snapshot_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "track_id": {
            "type": "string"
          }
        },
        "required": [
          "track_id",
          "repo",
          "branch",
          "alias",
          "created_at"
        ],
        "type": "object"
      },
      "GitlabUntracked": {
        "description": "`DELETE /v1/integrations/gitlab/tracks/{track_id}`: the snapshot stays; new commits no longer\nrebuild it.",
        "properties": {
          "alias": {
            "type": "string"
          },
          "branch": {
            "type": "string"
          },
          "repo": {
            "type": "string"
          },
          "track_id": {
            "type": "string"
          },
          "untracked": {
            "description": "Always true here.",
            "type": "boolean"
          }
        },
        "required": [
          "track_id",
          "repo",
          "branch",
          "alias",
          "untracked"
        ],
        "type": "object"
      },
      "GradeOutput": {
        "description": "What a sandbox's grader printed, kept because its run asked for it (`grade_output`). Only the\ngrader whose verdict decides the sandbox's outcome; a held-out grader reports its verdict and\nscore alone.",
        "properties": {
          "output": {
            "description": "The end of the grader's output, stdout and stderr together as it printed them: at most its\nlast 16 KiB.",
            "type": "string"
          },
          "output_truncated": {
            "description": "The grader printed more than `output` holds; the beginning was left out.",
            "type": "boolean"
          }
        },
        "required": [
          "output",
          "output_truncated"
        ],
        "type": "object"
      },
      "GradeSpec": {
        "description": "The `grade` block. Same shape on `POST /v1/runs` and on `snapshot create`, where it becomes\nthe snapshot's default grader.",
        "properties": {
          "cmd": {
            "description": "Runs in a fresh fork of the run's snapshot with the agent's changes applied.",
            "type": "string"
          },
          "holdout_cmd": {
            "description": "The customer's second test set — the one their agent never saw. Optional; its own fresh\nfork. Never our tests.",
            "type": [
              "string",
              "null"
            ]
          },
          "score": {
            "$ref": "#/components/schemas/ScoreMode",
            "default": "exit"
          },
          "timeout_ms": {
            "default": 600000,
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "cmd"
        ],
        "type": "object"
      },
      "GradeStats": {
        "description": "The two pass rates and the gap between them: `pass_pct − holdout_pass_pct`, in points.\n\n`None` when nothing was graded, or when no held-out set was run — there is no gap to quote\nfrom one test set.",
        "properties": {
          "gap_pct": {
            "description": "`pass_pct − holdout_pass_pct`, in points. The headline number.",
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "graded": {
            "description": "Sandboxes whose grader produced a verdict.",
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "grader_failed": {
            "default": 0,
            "description": "Sandboxes whose grader broke. Never counted as a task failure.",
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "holdout_graded": {
            "default": 0,
            "description": "Sandboxes whose held-out grader produced a verdict.",
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "holdout_pass_pct": {
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "holdout_passed": {
            "default": 0,
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "pass_pct": {
            "format": "double",
            "type": "number"
          },
          "passed": {
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "graded",
          "passed",
          "pass_pct"
        ],
        "type": "object"
      },
      "Guard": {
        "properties": {
          "name": {
            "type": "string"
          },
          "ok": {
            "type": "boolean"
          },
          "threshold": {},
          "value": {}
        },
        "required": [
          "name",
          "value",
          "threshold",
          "ok"
        ],
        "type": "object"
      },
      "Health": {
        "description": "`GET /v1/health` — liveness, and whether the service can start sandboxes. The cheapest call there is; use it\nas a readiness check.",
        "properties": {
          "build_sha": {
            "default": "",
            "description": "The commit this build came from; empty for a local build. Answered to a caller with a key;\nabsent for one without.",
            "type": "string"
          },
          "location": {
            "description": "Where sandboxes run, in plain words (for example \"US East Coast\"). Absent when the service\ndoes not say.",
            "type": [
              "string",
              "null"
            ]
          },
          "ok": {
            "type": "boolean"
          },
          "ready": {
            "description": "Whether new sandboxes can start right now. Answered to a request made with a key; absent\nwithout one.",
            "type": [
              "boolean",
              "null"
            ]
          },
          "serving": {
            "description": "Whether the service can start new sandboxes right now.",
            "type": [
              "boolean",
              "null"
            ]
          },
          "version": {
            "description": "The API's version.",
            "type": "string"
          }
        },
        "required": [
          "ok",
          "version"
        ],
        "type": "object"
      },
      "ImageResolve": {
        "additionalProperties": false,
        "description": "`POST /v1/images/resolve`.",
        "properties": {
          "image": {
            "description": "An image reference, a tag or a digest.",
            "type": "string"
          },
          "registry_secret": {
            "description": "A stored secret holding the registry credentials.",
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "image"
        ],
        "type": "object"
      },
      "ImageResolved": {
        "description": "`POST /v1/images/resolve` — a tag turned into a digest, ready for `POST /v1/snapshots`.",
        "properties": {
          "already_pinned": {
            "description": "True when the reference was already pinned and no registry was asked.",
            "type": "boolean"
          },
          "digest": {
            "description": "The digest `image` carries — the index's, for a tag that names several architectures,\nwhich is what a pull of that tag fetches.",
            "type": "string"
          },
          "image": {
            "description": "The pinned reference: your own name with `@sha256:…` on the end.",
            "type": "string"
          },
          "media_type": {
            "description": "The media type at that digest.",
            "type": "string"
          },
          "ms": {
            "description": "The round trip to the registry, in milliseconds.",
            "format": "double",
            "type": "number"
          },
          "ok": {
            "type": "boolean"
          },
          "platform": {
            "description": "`linux/amd64`.",
            "type": "string"
          },
          "platform_digest": {
            "description": "The `linux/amd64` build beside the index; `null` when the tag names a single manifest.",
            "type": [
              "string",
              "null"
            ]
          },
          "platforms": {
            "description": "Every `os/arch` the index offers. Empty for a single manifest.",
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "registry": {
            "type": "string"
          },
          "registry_secret": {
            "description": "The stored secret the registry was asked with, as it was named in the request.",
            "type": [
              "string",
              "null"
            ]
          },
          "repository": {
            "type": "string"
          },
          "tag": {
            "description": "`null` when the reference named a digest rather than a tag.",
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "ok",
          "image",
          "digest",
          "registry",
          "repository",
          "media_type",
          "platform",
          "platforms",
          "already_pinned",
          "ms"
        ],
        "type": "object"
      },
      "InviteCreate": {
        "additionalProperties": false,
        "description": "`POST /v1/orgs/{org}/invites`.",
        "properties": {
          "email": {
            "type": "string"
          },
          "role": {
            "description": "`owner` or `member` (default).",
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "email"
        ],
        "type": "object"
      },
      "InviteList": {
        "description": "`GET /v1/orgs/{org_id}/invites` and `GET /v1/invites`.",
        "properties": {
          "invites": {
            "items": {
              "$ref": "#/components/schemas/InviteView"
            },
            "type": "array"
          }
        },
        "required": [
          "invites"
        ],
        "type": "object"
      },
      "InviteRedeem": {
        "additionalProperties": false,
        "description": "`POST /v1/auth/invite`.",
        "properties": {
          "code": {
            "description": "The invite code.",
            "type": "string"
          },
          "nonce": {
            "description": "The sign-in attempt's login nonce.",
            "type": "string"
          }
        },
        "required": [
          "code",
          "nonce"
        ],
        "type": "object"
      },
      "InviteRedeemed": {
        "description": "`POST /v1/auth/invite` — an invite code redeemed for one sign-in attempt. The sign-in that\ncarries the same login nonce within `expires_in_s` may create an account; nothing else does.",
        "properties": {
          "expires_in_s": {
            "description": "Seconds the redeemed code holds this sign-in attempt's place (0 when invite mode is off).",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "invite_mode": {
            "description": "False when invite mode is off: no code is needed and none was looked at.",
            "type": "boolean"
          }
        },
        "required": [
          "invite_mode",
          "expires_in_s"
        ],
        "type": "object"
      },
      "InviteRelease": {
        "additionalProperties": false,
        "description": "`POST /v1/auth/invite/release`.",
        "properties": {
          "nonce": {
            "description": "The sign-in attempt's login nonce.",
            "type": "string"
          }
        },
        "required": [
          "nonce"
        ],
        "type": "object"
      },
      "InviteReleased": {
        "description": "`POST /v1/auth/invite/release` — a sign-in attempt that ended without an account gives back the\nplace its redeemed invite code held, so a retry can redeem the code again at once.",
        "properties": {
          "released": {
            "description": "True when this attempt held a place and gave it back; false when it held nothing (it never\nredeemed a code, its hold had lapsed, it already created the account, or invite mode is off).",
            "type": "boolean"
          }
        },
        "required": [
          "released"
        ],
        "type": "object"
      },
      "InviteRevoked": {
        "description": "`DELETE /v1/orgs/{org_id}/invites/{invite_id}`.",
        "properties": {
          "invite_id": {
            "type": "string"
          },
          "revoked": {
            "type": "boolean"
          }
        },
        "required": [
          "invite_id",
          "revoked"
        ],
        "type": "object"
      },
      "InviteView": {
        "description": "One pending invitation.",
        "properties": {
          "created_at": {
            "description": "RFC 3339.",
            "type": "string"
          },
          "email": {
            "description": "The address invited. Only a signed-in user whose verified email is this address can\naccept it.",
            "type": "string"
          },
          "invite_id": {
            "type": "string"
          },
          "invited_by": {
            "description": "The verified email of the owner who sent it, or `An owner of <org>` when that address is\nnot verified.",
            "type": "string"
          },
          "org_id": {
            "type": "string"
          },
          "org_name": {
            "type": "string"
          },
          "role": {
            "description": "`owner` or `member`.",
            "type": "string"
          }
        },
        "required": [
          "invite_id",
          "org_id",
          "org_name",
          "email",
          "role",
          "invited_by",
          "created_at"
        ],
        "type": "object"
      },
      "KeyCreate": {
        "additionalProperties": false,
        "description": "`POST /v1/keys`. Without `expires_in_days` or `expires_at` the key does not expire.",
        "properties": {
          "access": {
            "description": "`full` (the default) | `run` (sandboxes, runs and builds, whose runs can use the project's\nstored secrets; no changes to secrets, keys or billing) | `read` (reads everything in the\nproject, file contents and command output included; changes nothing).",
            "type": [
              "string",
              "null"
            ]
          },
          "expires_at": {
            "description": "A date (`2027-01-31`) or a UTC time ending in `Z`.",
            "type": [
              "string",
              "null"
            ]
          },
          "expires_in_days": {
            "description": "1–3650.",
            "format": "uint32",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "name": {
            "description": "Default `cli`, at most 64 characters.",
            "type": [
              "string",
              "null"
            ]
          }
        },
        "type": "object"
      },
      "KeyList": {
        "description": "`GET /v1/keys`.",
        "properties": {
          "keys": {
            "items": {
              "$ref": "#/components/schemas/KeyView"
            },
            "type": "array"
          },
          "org_id": {
            "type": "string"
          }
        },
        "required": [
          "org_id",
          "keys"
        ],
        "type": "object"
      },
      "KeyNetwork": {
        "description": "A network an API key was used from (`KeyView.networks`).",
        "properties": {
          "first_seen": {
            "description": "RFC 3339.",
            "type": "string"
          },
          "last_seen": {
            "description": "RFC 3339.",
            "type": "string"
          },
          "network": {
            "description": "An IPv4 `/24` (`203.0.113.0/24`) or an IPv6 `/64`.",
            "type": "string"
          }
        },
        "required": [
          "network",
          "first_seen",
          "last_seen"
        ],
        "type": "object"
      },
      "KeyRef": {
        "description": "A key named without its secret.",
        "properties": {
          "key_id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "prefix": {
            "description": "The first few characters, enough to recognise a key without holding it.",
            "type": "string"
          },
          "service": {
            "default": false,
            "description": "A project's service key (`POST /v1/orgs/{org}/keys` with `service: true`): it outlives\nits minter's membership and manages nothing. Absent from answers written before it existed.",
            "type": "boolean"
          }
        },
        "required": [
          "key_id",
          "prefix",
          "name"
        ],
        "type": "object"
      },
      "KeyView": {
        "description": "One API key. The secret itself is in `api_key`, on the 201 that minted it and nowhere else.",
        "properties": {
          "access": {
            "default": "full",
            "description": "What the key may do: `full`, `run` (sandboxes, runs and builds, whose runs can use the\nproject's stored secrets; no changes to secrets, keys or billing) or `read` (reads\neverything in the project, file contents and command output included; changes nothing).",
            "type": "string"
          },
          "also_revoked": {
            "description": "Only on the answer to `DELETE /v1/keys/{key_id}`: the key ids this revocation also\nrevoked, because the key had minted them (directly or further down). Absent when the key\nreplaced itself (`?reason=replaced`), which revokes nothing it minted.",
            "items": {
              "type": "string"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "api_key": {
            "description": "**The secret, and the only time it is ever sent.** Only on the 201 from\n`POST /v1/keys`; it cannot be retrieved afterwards.",
            "type": [
              "string",
              "null"
            ]
          },
          "created_at": {
            "description": "RFC 3339.",
            "type": "string"
          },
          "created_by": {
            "description": "The user who minted it; `null` for a key minted by another key.",
            "type": [
              "string",
              "null"
            ]
          },
          "current": {
            "description": "True for the key this request was made with. Absent from the answer that mints a key,\nwhich is not yet the key you are calling with.",
            "type": [
              "boolean",
              "null"
            ]
          },
          "expires_at": {
            "default": null,
            "description": "RFC 3339: when the key stops working, as chosen when it was created. `null` = it does\nnot expire (the default). An expired key answers `key_expired`.",
            "type": [
              "string",
              "null"
            ]
          },
          "key_id": {
            "type": "string"
          },
          "last_used_at": {
            "description": "RFC 3339; `null` for a key that has never been used.",
            "type": [
              "string",
              "null"
            ]
          },
          "minted_by": {
            "default": null,
            "description": "The key that minted this one; `null` for a key minted by a sign-in. Revoking a key\nrevokes every key it minted, and every key those minted.",
            "type": [
              "string",
              "null"
            ]
          },
          "name": {
            "type": "string"
          },
          "networks": {
            "description": "The networks the key was used from, most recent first (at most 20): each an IPv4 `/24` or\nan IPv6 `/64`, never a full address, with when it was first and last seen there. On the\nkey list; absent elsewhere.",
            "items": {
              "$ref": "#/components/schemas/KeyNetwork"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "prefix": {
            "description": "The first few characters, enough to recognise a key without holding it.",
            "type": "string"
          },
          "revoked": {
            "description": "Only on the answer to `DELETE /v1/keys/{key_id}`.",
            "type": [
              "boolean",
              "null"
            ]
          },
          "revoked_at": {
            "description": "RFC 3339; `null` while the key still works.",
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "key_id",
          "prefix",
          "name",
          "created_at"
        ],
        "type": "object"
      },
      "LastCheck": {
        "description": "The most recent synthetic check.",
        "properties": {
          "age_s": {
            "description": "How old it is, in seconds.",
            "format": "int64",
            "type": "integer"
          },
          "api_ok": {
            "description": "Whether the API answered, independently of the full check.",
            "type": "boolean"
          },
          "at": {
            "description": "RFC 3339.",
            "type": "string"
          },
          "e2e_ms": {
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "ok": {
            "type": "boolean"
          },
          "step": {
            "description": "The step the check reached.",
            "type": "string"
          }
        },
        "required": [
          "at",
          "age_s",
          "ok",
          "api_ok",
          "step"
        ],
        "type": "object"
      },
      "LatencyStats": {
        "description": "Percentiles of a latency sample, in milliseconds; each `null` when the sample is empty.",
        "properties": {
          "max": {
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "p50": {
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "p95": {
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          }
        },
        "type": "object"
      },
      "LedgerEntryView": {
        "description": "One charge: what it was for, the seconds it counted and the rates it used.",
        "properties": {
          "amount": {
            "description": "USD.",
            "format": "double",
            "type": "number"
          },
          "created_at": {
            "description": "RFC 3339.",
            "type": "string"
          },
          "detail": {
            "description": "Why this amount: the outcome for a sandbox's final charge, `interim` for one recorded while\nit ran.",
            "type": "string"
          },
          "entry_id": {
            "type": "string"
          },
          "episodes": {
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "gib_second_usd": {
            "format": "double",
            "type": "number"
          },
          "interim": {
            "description": "True for a charge recorded while the sandbox was still running; its final charge follows\nwhen it ends.",
            "type": "boolean"
          },
          "kind": {
            "description": "`sandbox` | `build` | `egress` | …",
            "type": "string"
          },
          "mem_gib": {
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "run_id": {
            "description": "The run this charge belongs to; `null` for a charge that has none (a build).",
            "type": [
              "string",
              "null"
            ]
          },
          "sandbox_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "seconds": {
            "description": "Billable seconds this row charges; negative for a reversal.",
            "format": "int64",
            "type": "integer"
          },
          "subject": {
            "description": "What was charged: a sandbox id or a build id; for credit, what it is for (e.g. \"Credit from Promigence\").",
            "type": "string"
          },
          "tier": {
            "type": "string"
          },
          "unit": {
            "description": "The per-second rate, in USD.",
            "format": "double",
            "type": "number"
          },
          "vcpu_second_usd": {
            "format": "double",
            "type": "number"
          },
          "vcpus": {
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "entry_id",
          "kind",
          "subject",
          "tier",
          "unit",
          "episodes",
          "seconds",
          "vcpus",
          "mem_gib",
          "vcpu_second_usd",
          "gib_second_usd",
          "interim",
          "amount",
          "detail",
          "created_at"
        ],
        "type": "object"
      },
      "LedgerList": {
        "description": "`GET /v1/me/ledger` — the charges behind `spend`. With a project's key: that project's\nrows and the organization's credit grants; `spend` stays the organization's.",
        "properties": {
          "entries": {
            "description": "Newest first.",
            "items": {
              "$ref": "#/components/schemas/LedgerEntryView"
            },
            "type": "array"
          },
          "next_cursor": {
            "default": null,
            "description": "Pass as `?cursor=` for the next page; `null` on the last one.",
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "entries"
        ],
        "type": "object"
      },
      "Lockfile": {
        "properties": {
          "digest": {
            "type": "string"
          },
          "frozen": {
            "type": "boolean"
          },
          "path": {
            "type": "string"
          }
        },
        "required": [
          "path",
          "digest",
          "frozen"
        ],
        "type": "object"
      },
      "Me": {
        "description": "`GET /v1/me` — who you are, what your limits are, what you have spent, and what trial credit\nis left.",
        "properties": {
          "card_on_file": {
            "type": "boolean"
          },
          "concurrency": {
            "$ref": "#/components/schemas/MeConcurrency",
            "default": {
              "in_use": 0,
              "limit": 0
            },
            "description": "Live sandboxes now, against the organisation's limit."
          },
          "default_spend_cap": {
            "description": "The cap a run gets when it names none, in USD.",
            "format": "double",
            "type": "number"
          },
          "key": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/KeyRef"
              },
              {
                "type": "null"
              }
            ],
            "description": "The key this request was made with."
          },
          "limits": {
            "$ref": "#/components/schemas/MeLimits"
          },
          "location": {
            "description": "Where sandboxes run, in plain words (for example \"US East Coast\"), as `GET /v1/health` says\nit. Absent when the service does not say.",
            "type": [
              "string",
              "null"
            ]
          },
          "location_code": {
            "description": "The same place as a short code, for example `us-east`. Only beside `location`; new codes may\nappear, and a code you do not know is fine to ignore.",
            "type": [
              "string",
              "null"
            ]
          },
          "notice": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/TrialNotice"
              },
              {
                "type": "null"
              }
            ],
            "description": "A notice about a coming change to the trial rules; `null` when there is none."
          },
          "org": {
            "description": "The organisation's name.",
            "type": "string"
          },
          "org_id": {
            "type": "string"
          },
          "plan": {
            "default": "",
            "description": "The plan the organisation's limits and prices come from: `hobby` for a trial\norganisation with no plan assigned.",
            "type": "string"
          },
          "spend": {
            "description": "What the organisation has spent, in USD. Absent for a key that may not see the\norganisation's money (see `trial`).",
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "spend_detail": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/SpendDetail"
              },
              {
                "type": "null"
              }
            ]
          },
          "trial": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/TrialStatus"
              },
              {
                "type": "null"
              }
            ],
            "description": "The organisation's trial credit. Absent for a key that may not see the organisation's\nmoney: only an owner's key of the default project does."
          },
          "user": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/UserView"
              },
              {
                "type": "null"
              }
            ],
            "description": "The user behind the key this request was made with; `null` for a key minted by an\noperator."
          }
        },
        "required": [
          "org",
          "org_id",
          "limits",
          "default_spend_cap",
          "card_on_file"
        ],
        "type": "object"
      },
      "MeConcurrency": {
        "description": "How many sandboxes count against your concurrency limit now, and how many may.",
        "properties": {
          "in_use": {
            "description": "Sandboxes queued, starting, ready or running. A paused sandbox is not counted.",
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "limit": {
            "description": "The most that may be live at once: `limits.max_concurrency`.",
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "in_use",
          "limit"
        ],
        "type": "object"
      },
      "MeLimits": {
        "description": "The limits in force for an organisation.",
        "properties": {
          "max_concurrency": {
            "description": "Sandboxes that may be live at once.",
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "max_inflight": {
            "description": "Sandboxes that may be starting at once.",
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "max_sandbox_vcpus": {
            "description": "The largest sandbox shape, in vCPU; `null` for no limit.",
            "format": "uint32",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "max_session_s": {
            "description": "The longest a sandbox may live, in seconds; `null` for no limit.",
            "format": "uint64",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          }
        },
        "required": [
          "max_inflight",
          "max_concurrency"
        ],
        "type": "object"
      },
      "MemberList": {
        "description": "`GET /v1/orgs/{org_id}/members`.",
        "properties": {
          "members": {
            "items": {
              "$ref": "#/components/schemas/MemberView"
            },
            "type": "array"
          },
          "org_id": {
            "type": "string"
          }
        },
        "required": [
          "org_id",
          "members"
        ],
        "type": "object"
      },
      "MemberRemoved": {
        "description": "`DELETE /v1/orgs/{org_id}/members/{user_id}` — a member removed, or you left.",
        "properties": {
          "keys_revoked": {
            "description": "Keys that person had minted for themselves in this organization, now revoked. Service\nkeys keep working.",
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "org_id": {
            "type": "string"
          },
          "removed": {
            "type": "boolean"
          },
          "user_id": {
            "type": "string"
          }
        },
        "required": [
          "org_id",
          "user_id",
          "removed",
          "keys_revoked"
        ],
        "type": "object"
      },
      "MemberRoleSet": {
        "additionalProperties": false,
        "description": "`PATCH /v1/orgs/{org}/members/{user_id}`.",
        "properties": {
          "role": {
            "description": "`owner` or `member`.",
            "type": "string"
          }
        },
        "required": [
          "role"
        ],
        "type": "object"
      },
      "MemberView": {
        "description": "One member of an organization.",
        "properties": {
          "email": {
            "type": "string"
          },
          "joined_at": {
            "description": "RFC 3339.",
            "type": "string"
          },
          "role": {
            "description": "`owner` or `member`.",
            "type": "string"
          },
          "user_id": {
            "type": "string"
          },
          "you": {
            "description": "True for the member making this request.",
            "type": "boolean"
          }
        },
        "required": [
          "user_id",
          "email",
          "role",
          "joined_at",
          "you"
        ],
        "type": "object"
      },
      "MethodCheckView": {
        "description": "The $1 charged to confirm a payment method with no stable payer (`GET /v1/billing`\n`method_check`).",
        "properties": {
          "amount_usd": {
            "description": "USD charged; added to your credit once paid.",
            "format": "double",
            "type": "number"
          },
          "bonus_usd": {
            "description": "USD of credit that came with it (the card bonus), once paid; `null` otherwise.",
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "method": {
            "description": "The method as a person reads it: `Apple Pay`, `Google Pay`, `Amazon Pay`, ...",
            "type": "string"
          },
          "status": {
            "description": "`confirming` (charged, its answer not in yet), `paid` (it counts as your payment method) or\n`failed` (declined, or it needed you there to approve it: it does not count; add a card).",
            "type": "string"
          }
        },
        "required": [
          "method",
          "status",
          "amount_usd"
        ],
        "type": "object"
      },
      "NameCreate": {
        "additionalProperties": false,
        "description": "`POST /v1/orgs` and `POST /v1/orgs/{org}/projects`.",
        "properties": {
          "name": {
            "description": "1–40 lowercase letters, digits and dashes.",
            "type": "string"
          }
        },
        "required": [
          "name"
        ],
        "type": "object"
      },
      "Network": {
        "enum": [
          "none",
          "egress"
        ],
        "type": "string",
        "x-promigence-open-enum": true
      },
      "NetworkAllow": {
        "additionalProperties": false,
        "description": "An allowlist: the only hosts the sandbox may reach.",
        "properties": {
          "allow": {
            "description": "Host names (a leading `*.` matches subdomains). At least one.",
            "items": {
              "type": "string"
            },
            "type": "array"
          }
        },
        "required": [
          "allow"
        ],
        "type": "object"
      },
      "NetworkMode": {
        "description": "A network policy named by its mode alone.",
        "properties": {
          "mode": {
            "description": "`\"none\"`.",
            "type": "string"
          }
        },
        "required": [
          "mode"
        ],
        "type": "object"
      },
      "NetworkRequest": {
        "anyOf": [
          {
            "description": "`egress` or `none`.",
            "type": "string"
          },
          {
            "$ref": "#/components/schemas/NetworkAllow",
            "description": "Only these hosts are reachable."
          }
        ],
        "description": "A run's network: `\"egress\"` (the default), `\"none\"`, or `{\"allow\": [\"host\", …]}`."
      },
      "NumberOrName": {
        "anyOf": [
          {
            "format": "int64",
            "type": "integer"
          },
          {
            "type": "string"
          }
        ],
        "description": "A number, or a string."
      },
      "OneOrMany": {
        "anyOf": [
          {
            "type": "string"
          },
          {
            "items": {
              "type": "string"
            },
            "type": "array"
          }
        ],
        "description": "One string, or a list of them."
      },
      "OptimizeFor": {
        "description": "What to favour: `start` (fast, wide starts) or `compute` (raw speed for long, memory-heavy jobs on tiers of 15 GiB or more). It changes nothing on smaller sandboxes. Default: `start`.",
        "enum": [
          "start",
          "compute"
        ],
        "type": "string",
        "x-promigence-open-enum": true
      },
      "OrgDelete": {
        "additionalProperties": false,
        "description": "`DELETE /v1/orgs/{org}`.",
        "properties": {
          "confirm": {
            "description": "The organization's name, typed out.",
            "type": "string"
          }
        },
        "required": [
          "confirm"
        ],
        "type": "object"
      },
      "OrgDeleted": {
        "description": "`DELETE /v1/orgs/{org_id}` — an organization deleted.",
        "properties": {
          "deleted": {
            "type": "boolean"
          },
          "keys_revoked": {
            "description": "Keys that stopped working (every key of the organization).",
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "members_rehomed": {
            "description": "Members it was the last organization of, each given a fresh personal one.",
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "org_id": {
            "type": "string"
          }
        },
        "required": [
          "org_id",
          "deleted",
          "keys_revoked",
          "members_rehomed"
        ],
        "type": "object"
      },
      "OrgKeyCreate": {
        "additionalProperties": false,
        "description": "`POST /v1/orgs/{org}/keys`.",
        "properties": {
          "access": {
            "description": "`full` (the default) | `run` (sandboxes, runs and builds, whose runs can use the project's\nstored secrets; no changes to secrets, keys or billing) | `read` (reads everything in the\nproject, file contents and command output included; changes nothing).",
            "type": [
              "string",
              "null"
            ]
          },
          "default": {
            "description": "Also make this organization your default.",
            "type": "boolean"
          },
          "expires_at": {
            "description": "A date or a UTC time ending in `Z`.",
            "type": [
              "string",
              "null"
            ]
          },
          "expires_in_days": {
            "description": "1–3650.",
            "format": "uint32",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "expires_in_minutes": {
            "description": "1–1440: a short-lived key, its lifetime counted on the server's clock.",
            "format": "uint32",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "name": {
            "description": "Default `cli`, at most 64 characters.",
            "type": [
              "string",
              "null"
            ]
          },
          "project": {
            "description": "A project id or name. Default: the calling key's project, or the default project.",
            "type": [
              "string",
              "null"
            ]
          },
          "service": {
            "description": "A service key: not tied to a person.",
            "type": "boolean"
          }
        },
        "type": "object"
      },
      "OrgKeyView": {
        "description": "`POST /v1/orgs/{org_id}/keys` — a key minted in an organization and project you belong to.",
        "properties": {
          "access": {
            "default": "full",
            "description": "What the key may do: `full`, `run` (sandboxes, runs and builds, whose runs can use the\nproject's stored secrets; no changes to secrets, keys or billing) or `read` (reads\neverything in the project, file contents and command output included; changes nothing).",
            "type": "string"
          },
          "api_key": {
            "description": "**The secret, and the only time it is ever sent.**",
            "type": "string"
          },
          "created_at": {
            "description": "RFC 3339.",
            "type": "string"
          },
          "created_by": {
            "description": "The user who minted it.",
            "type": [
              "string",
              "null"
            ]
          },
          "expires_at": {
            "default": null,
            "description": "RFC 3339: when the key stops working, as chosen when it was created. `null` = it does\nnot expire (the default).",
            "type": [
              "string",
              "null"
            ]
          },
          "key_id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "org_id": {
            "type": "string"
          },
          "prefix": {
            "type": "string"
          },
          "project_id": {
            "type": "string"
          },
          "service": {
            "description": "A service key (CI, a worker pool) keeps working when the member who minted it leaves; a\nmember's own key is revoked with their membership.",
            "type": "boolean"
          }
        },
        "required": [
          "key_id",
          "prefix",
          "name",
          "org_id",
          "project_id",
          "service",
          "created_at",
          "api_key"
        ],
        "type": "object"
      },
      "OrgList": {
        "description": "`GET /v1/orgs`.",
        "properties": {
          "orgs": {
            "items": {
              "$ref": "#/components/schemas/OrgView"
            },
            "type": "array"
          }
        },
        "required": [
          "orgs"
        ],
        "type": "object"
      },
      "OrgPatch": {
        "additionalProperties": false,
        "description": "`PATCH /v1/orgs/{org}`: rename the organization. Its id never changes; anything that names\nit by the old name (a script, `--org`, a saved URL) must use the new one.",
        "properties": {
          "name": {
            "description": "1–40 lowercase letters, digits and dashes.",
            "type": "string"
          }
        },
        "required": [
          "name"
        ],
        "type": "object"
      },
      "OrgView": {
        "description": "One organization you belong to. Billing, members and credits belong to it.",
        "properties": {
          "card_on_file": {
            "description": "A payment method is on file.",
            "type": "boolean"
          },
          "created_at": {
            "description": "RFC 3339.",
            "type": "string"
          },
          "default": {
            "description": "True for the organization a sign-in and the CLI use when none is named.",
            "type": "boolean"
          },
          "members": {
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "org_id": {
            "type": "string"
          },
          "projects": {
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "role": {
            "description": "Your role in it: `owner` or `member`.",
            "type": "string"
          }
        },
        "required": [
          "org_id",
          "name",
          "role",
          "default",
          "card_on_file",
          "projects",
          "members",
          "created_at"
        ],
        "type": "object"
      },
      "OtherUsage": {
        "description": "A charge of another kind.",
        "properties": {
          "amount": {
            "description": "USD.",
            "format": "double",
            "type": "number"
          },
          "entries": {
            "format": "int64",
            "type": "integer"
          }
        },
        "required": [
          "entries",
          "amount"
        ],
        "type": "object"
      },
      "Outcome": {
        "oneOf": [
          {
            "enum": [
              "completed",
              "task_failed",
              "env_failed",
              "snapshot_failed",
              "aborted_by_client",
              "expired",
              "cap_killed",
              "not_started",
              "superseded"
            ],
            "type": "string"
          },
          {
            "const": "grader_failed",
            "description": "The episode ran; the grade did not. The episode's compute is billed, and so is the time\nthe grader ran when it ran and failed on its own; a grade that failed on our side is not.",
            "type": "string"
          },
          {
            "const": "preempted",
            "description": "A preemptible sandbox was stopped early, as preemptible runs can be. Unbilled, and **not**\n`env_failed`: its failure category is `preempt`.",
            "type": "string"
          },
          {
            "const": "stopped_by_support",
            "description": "Promigence support stopped it; the failure's `reason` says why. Billed for the seconds it\nran, as a kill is, unless support found the cause was on our side; then that time is\ncredited back. Not the customer's own kill (`aborted_by_client`) and not a failure.",
            "type": "string"
          }
        ],
        "x-promigence-open-enum": true
      },
      "Outcomes": {
        "description": "`GET /v1/me/outcomes?period=month` — what the organization (with a project's key: that project)\ngot this period, measured from its own runs and sandboxes. A figure with nothing behind it is\n`null`; counts are `0`.",
        "properties": {
          "batch_runs": {
            "description": "Finished runs of two or more sandboxes this period.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "batch_saved_s": {
            "description": "For those runs: seconds not spent waiting, the sum of their sandboxes' own times minus\nthe runs' wall time; `null` without such a run.",
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "batch_speedup": {
            "description": "For those runs: the sum of their sandboxes' own times divided by the runs' wall time\n(how many times faster than one after another); `null` without such a run.",
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "failures_ours": {
            "description": "Sandboxes that ended on a failure on our side and were not billed for it.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "failures_ours_usd": {
            "description": "What was given back for those failures, in USD (`0` when they ended before any charge).",
            "format": "double",
            "type": "number"
          },
          "kept_failures": {
            "description": "Failed sandboxes kept to reopen that can still be reopened.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "paused_hours": {
            "description": "Hours this period's sandboxes spent paused, which is not billed; `null` if none paused.",
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "paused_usd": {
            "description": "What those paused hours would have cost running, in USD; `null` if none paused.",
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "period": {
            "description": "`month`: the calendar month so far, UTC.",
            "type": "string"
          },
          "ready_ms_p50": {
            "description": "The median milliseconds until a sandbox was ready to take work; `null` with no sandbox.",
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "runs": {
            "description": "Runs started this period.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "sandboxes": {
            "description": "Sandboxes started this period.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "since": {
            "description": "When the period began (RFC 3339, UTC).",
            "type": "string"
          }
        },
        "required": [
          "period",
          "since",
          "runs",
          "sandboxes",
          "failures_ours",
          "failures_ours_usd",
          "kept_failures",
          "batch_runs"
        ],
        "type": "object"
      },
      "ParkedBytes": {
        "description": "What a parked sandbox occupies on disk.",
        "properties": {
          "allocated": {
            "description": "Bytes on disk.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "allocated"
        ],
        "type": "object"
      },
      "Payment": {
        "description": "A payment: an invoice paid, a payment that failed, a refund, or the charge that confirmed a\npayment method.",
        "properties": {
          "amount_usd": {
            "description": "USD: what was paid, what was due, what was refunded, or what confirmed the method.",
            "format": "double",
            "type": "number"
          },
          "invoice_number": {
            "description": "The invoice's number, as the invoice shows it; `null` when not known.",
            "type": [
              "string",
              "null"
            ]
          },
          "invoice_url": {
            "description": "The invoice's page: its receipt once it is paid, where to pay it while a payment has\nfailed; `null` when not known.",
            "type": [
              "string",
              "null"
            ]
          },
          "kind": {
            "description": "`invoice_paid`, `payment_failed`, `refund`, or `method_check` (a charge, usually $1, that\nconfirmed a payment method; it comes back as credit).",
            "type": "string"
          },
          "method": {
            "description": "`method_check`: the payment method it confirmed, by name (`Apple Pay`); `null` otherwise.",
            "type": [
              "string",
              "null"
            ]
          },
          "plan": {
            "description": "The plan whose fee the invoice billed; `null` when it billed usage alone.",
            "type": [
              "string",
              "null"
            ]
          },
          "status": {
            "description": "`paid` (for a payment that failed: paid since), `retrying` (it failed and will be tried\nagain), `failed` (it failed and will not be tried again; for `method_check`, the method\nwas not confirmed), `refunded`, or `confirmed` (`method_check`: the method is confirmed).",
            "type": "string"
          }
        },
        "required": [
          "kind",
          "amount_usd",
          "status"
        ],
        "type": "object"
      },
      "Percentiles": {
        "properties": {
          "p50": {
            "format": "double",
            "type": "number"
          },
          "p95": {
            "format": "double",
            "type": "number"
          },
          "p99": {
            "description": "Only present when n ≥ 100.",
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          }
        },
        "required": [
          "p50",
          "p95"
        ],
        "type": "object"
      },
      "PeriodUsage": {
        "description": "What a period cost, by what it was spent on.",
        "properties": {
          "billable": {
            "description": "What is left for the card.",
            "format": "double",
            "type": "number"
          },
          "builds": {
            "$ref": "#/components/schemas/BuildUsage"
          },
          "credits_applied": {
            "description": "Of `total`, what trial credits paid.",
            "format": "double",
            "type": "number"
          },
          "currency": {
            "description": "`usd`.",
            "type": "string"
          },
          "egress": {
            "$ref": "#/components/schemas/EgressUsage"
          },
          "legacy_episodes": {
            "additionalProperties": {
              "$ref": "#/components/schemas/EpisodeUsage"
            },
            "description": "Per-episode rows from an older pricing model; only for a period that has them.",
            "type": [
              "object",
              "null"
            ]
          },
          "other": {
            "additionalProperties": {
              "$ref": "#/components/schemas/OtherUsage"
            },
            "description": "Any other kind of charge, by kind.",
            "type": "object"
          },
          "sandboxes": {
            "additionalProperties": {
              "$ref": "#/components/schemas/SandboxUsage"
            },
            "description": "Sandbox time by tier.",
            "type": "object"
          },
          "total": {
            "description": "USD.",
            "format": "double",
            "type": "number"
          },
          "unreported_entries": {
            "description": "Charges not yet reported to the payment provider.",
            "format": "int64",
            "type": "integer"
          }
        },
        "required": [
          "sandboxes",
          "builds",
          "egress",
          "other",
          "total",
          "credits_applied",
          "billable",
          "currency",
          "unreported_entries"
        ],
        "type": "object"
      },
      "Port": {
        "description": "One preview URL. Anyone holding the URL can reach the port behind it — it is a bearer token in\na link.",
        "properties": {
          "created_unix_ns": {
            "description": "Unix nanoseconds.",
            "format": "uint64",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "host_url_label": {
            "description": "The same publication addressed by name rather than by path. Apps that emit absolute paths\nneed this form.",
            "type": [
              "string",
              "null"
            ]
          },
          "port": {
            "description": "The port inside the sandbox.",
            "format": "uint64",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "sandbox_id": {
            "type": "string"
          },
          "token": {
            "description": "The token the URL carries. Pass it to `DELETE /v1/sandboxes/{id}/ports/{token_or_port}` to\nrevoke this one URL.",
            "type": [
              "string",
              "null"
            ]
          },
          "url": {
            "description": "The URL to open.",
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "sandbox_id"
        ],
        "type": "object"
      },
      "PortList": {
        "description": "`GET /v1/sandboxes/{id}/ports`.",
        "properties": {
          "ports": {
            "items": {
              "$ref": "#/components/schemas/Port"
            },
            "type": "array"
          },
          "sandbox_id": {
            "type": "string"
          }
        },
        "required": [
          "sandbox_id",
          "ports"
        ],
        "type": "object"
      },
      "PortOpen": {
        "additionalProperties": false,
        "description": "`POST /v1/sandboxes/{id}/ports`.",
        "properties": {
          "port": {
            "description": "1–65535.",
            "format": "uint16",
            "maximum": 65535,
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "port"
        ],
        "type": "object"
      },
      "PortalSession": {
        "description": "`POST /v1/billing/portal` — a link to the billing portal.",
        "properties": {
          "url": {
            "type": "string"
          }
        },
        "required": [
          "url"
        ],
        "type": "object"
      },
      "PortsRevoked": {
        "description": "`DELETE /v1/sandboxes/{id}/ports/{token_or_port}`.",
        "properties": {
          "ok": {
            "type": "boolean"
          },
          "revoked": {
            "description": "The tokens that were revoked. Revoking by port number revokes every URL minted for that\nport, so this can hold more than one.",
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "sandbox_id": {
            "type": "string"
          }
        },
        "required": [
          "ok",
          "sandbox_id",
          "revoked"
        ],
        "type": "object"
      },
      "PricingFreeCredit": {
        "description": "The free credit a new account gets. An account's own credit, and whether it can still claim\nit, is `GET /v1/credits/offer`.",
        "properties": {
          "card_bonus_usd": {
            "description": "More free credit when a card is first added, USD; 0 when the offer has ended.",
            "format": "double",
            "type": "number"
          },
          "expires_by": {
            "description": "Free credit ends at this instant at the latest, whenever it was granted (RFC 3339); `null`\nfor no fixed end.",
            "type": [
              "string",
              "null"
            ]
          },
          "expiry_days_after_claim": {
            "description": "Free credit expires this many days after it is granted; `null` when no such rule applies.",
            "format": "int64",
            "type": [
              "integer",
              "null"
            ]
          },
          "invite_required": {
            "description": "New accounts need an invite code right now (`promigence signup`); a code may carry its own\nfree credit in place of `signup_credit_usd`.",
            "type": "boolean"
          },
          "signup_credit_usd": {
            "description": "Free credit a new account claims once, in the browser (`promigence credits claim`), USD;\n0 when the offer has ended.",
            "format": "double",
            "type": "number"
          },
          "terms_url": {
            "description": "The terms free credit is given under.",
            "type": "string"
          }
        },
        "required": [
          "signup_credit_usd",
          "card_bonus_usd",
          "terms_url",
          "invite_required"
        ],
        "type": "object"
      },
      "PricingLimits": {
        "description": "The limits in force.",
        "properties": {
          "build_max_s": {
            "description": "The longest a snapshot build may run, in seconds, and so the most seconds one build is\nbilled for.",
            "format": "uint64",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "default_timeout_s": {
            "description": "A sandbox's timeout when its run names none, in seconds.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "egress_gb_month": {
            "description": "Data out included each month, in GiB; `null` when none is included.",
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "max_concurrency": {
            "description": "Sandboxes that may be live at once; `null` for no limit.",
            "format": "uint32",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "max_count_per_run": {
            "description": "The most sandboxes one run may start.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "max_egress_gb_month": {
            "description": "Where data out stops each month, in GiB; `null` when it does not stop.",
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "max_sandbox_vcpus": {
            "description": "The largest sandbox shape, in vCPU; `null` for no limit.",
            "format": "uint32",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "max_session_s": {
            "description": "The longest a sandbox may live, in seconds, extensions included.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "smtp": {
            "description": "Whether outbound mail ports are open.",
            "type": "boolean"
          }
        },
        "required": [
          "max_session_s",
          "default_timeout_s",
          "max_count_per_run",
          "smtp"
        ],
        "type": "object"
      },
      "PricingPlan": {
        "description": "The plan the prices and limits come from.",
        "properties": {
          "display_name": {
            "type": "string"
          },
          "on_trial": {
            "description": "Trial rules apply: work is paid from free credit, within the trial's limits, until a card is\nadded.",
            "type": "boolean"
          },
          "plan_id": {
            "description": "The plan's id: the name `promigence me` shows as `plan`.",
            "type": "string"
          },
          "version": {
            "description": "The version of the plan these values come from; `null` when none is assigned and the\nstandard values apply.",
            "format": "int64",
            "type": [
              "integer",
              "null"
            ]
          }
        },
        "required": [
          "plan_id",
          "display_name",
          "on_trial"
        ],
        "type": "object"
      },
      "PricingRates": {
        "description": "The rates, USD.",
        "properties": {
          "build_usd": {
            "description": "The most one snapshot build of the default tier can cost: `limits.build_max_s` seconds at\nthat tier's per-second rate. A build is billed per second at its own tier's rate (`tiers`)\nfor the time it runs, whether it is stored, its own `setup` or `verify` fails, or it runs to\nits time limit; a failure on our side, and reusing or joining an identical build, cost\nnothing.",
            "format": "double",
            "type": "number"
          },
          "egress_gb_usd": {
            "description": "Data out, per GiB above the month's included allowance (`limits.egress_gb_month`); `null`\nwhen data out is not priced.",
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "gib_second_usd": {
            "description": "Per GiB of memory, per second.",
            "format": "double",
            "type": "number"
          },
          "preemptible_gib_second_usd": {
            "description": "Per GiB of memory, per second, for a run started `preemptible`.",
            "format": "double",
            "type": "number"
          },
          "preemptible_vcpu_second_usd": {
            "description": "Per vCPU, per second, for a run started `preemptible` (such a run can be stopped early; a\nsandbox stopped that way is credited back, like any failure on our side).",
            "format": "double",
            "type": "number"
          },
          "storage_gb_month_usd": {
            "description": "Stored snapshot data, per GiB-month; `null` while storage is not billed (today: it is\nnot).",
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "vcpu_second_usd": {
            "description": "Per vCPU, per second.",
            "format": "double",
            "type": "number"
          }
        },
        "required": [
          "vcpu_second_usd",
          "gib_second_usd",
          "preemptible_vcpu_second_usd",
          "preemptible_gib_second_usd",
          "build_usd"
        ],
        "type": "object"
      },
      "PricingTier": {
        "description": "One sandbox shape and its price.",
        "properties": {
          "available": {
            "description": "Within this account's largest sandbox shape (`limits.max_sandbox_vcpus`), so it can be\nbuilt and run now.",
            "type": "boolean"
          },
          "disk_gib": {
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "mem_gib": {
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "name": {
            "description": "The name `--tier` takes.",
            "type": "string"
          },
          "per_hour_usd": {
            "description": "USD per hour, on demand.",
            "format": "double",
            "type": "number"
          },
          "per_second_usd": {
            "description": "USD per second, on demand.",
            "format": "double",
            "type": "number"
          },
          "preemptible_per_second_usd": {
            "description": "USD per second for a run started `preemptible`.",
            "format": "double",
            "type": "number"
          },
          "vcpus": {
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "name",
          "vcpus",
          "mem_gib",
          "disk_gib",
          "per_second_usd",
          "per_hour_usd",
          "preemptible_per_second_usd",
          "available"
        ],
        "type": "object"
      },
      "PricingView": {
        "description": "`GET /v1/pricing` — the prices, sandbox shapes, limits and free credit in force for the key's\norganisation, read on every call from the same place billing charges from. A key is required.\nA run is billed at the rates in force when it was created, so a later change to these values\nnever reprices a run already started.",
        "properties": {
          "as_of": {
            "description": "When these values were read, RFC 3339. They can change at any time: read them again rather\nthan keeping a copy.",
            "type": "string"
          },
          "billing": {
            "description": "`per_second`: a sandbox bills `(vcpus × vcpu_second_usd + mem_gib × gib_second_usd) ×\nbillable seconds`, from hand-over to end, minus paused time.",
            "type": "string"
          },
          "currency": {
            "description": "`usd`.",
            "type": "string"
          },
          "free_credit": {
            "$ref": "#/components/schemas/PricingFreeCredit"
          },
          "granularity_seconds": {
            "description": "Billable seconds are rounded up to this many.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "included_credits_usd": {
            "description": "Usage the monthly fee includes each month, USD.",
            "format": "double",
            "type": "number"
          },
          "limits": {
            "$ref": "#/components/schemas/PricingLimits"
          },
          "min_billable_seconds": {
            "description": "The fewest seconds a sandbox that ran is billed.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "monthly_fee_usd": {
            "description": "The plan's monthly fee, USD.",
            "format": "double",
            "type": "number"
          },
          "monthly_minimum_usd": {
            "description": "A committed monthly minimum, USD; 0 for none.",
            "format": "double",
            "type": "number"
          },
          "org_id": {
            "description": "The organisation these values are for.",
            "type": "string"
          },
          "plan": {
            "$ref": "#/components/schemas/PricingPlan"
          },
          "rates": {
            "$ref": "#/components/schemas/PricingRates"
          },
          "schema": {
            "description": "`promigence.pricing/v1`.",
            "type": "string"
          },
          "scope": {
            "description": "`organization`: what the key's organisation pays.",
            "type": "string"
          },
          "tiers": {
            "description": "Every sandbox shape on sale, smallest first, priced at these rates.",
            "items": {
              "$ref": "#/components/schemas/PricingTier"
            },
            "type": "array"
          }
        },
        "required": [
          "schema",
          "as_of",
          "currency",
          "scope",
          "org_id",
          "plan",
          "billing",
          "granularity_seconds",
          "min_billable_seconds",
          "rates",
          "tiers",
          "limits",
          "free_credit",
          "monthly_fee_usd",
          "included_credits_usd",
          "monthly_minimum_usd"
        ],
        "type": "object"
      },
      "ProjectDeleted": {
        "description": "`DELETE /v1/orgs/{org_id}/projects/{project_id}`.",
        "properties": {
          "deleted": {
            "type": "boolean"
          },
          "project_id": {
            "type": "string"
          }
        },
        "required": [
          "project_id",
          "deleted"
        ],
        "type": "object"
      },
      "ProjectList": {
        "description": "`GET /v1/orgs/{org_id}/projects`.",
        "properties": {
          "org_id": {
            "type": "string"
          },
          "projects": {
            "items": {
              "$ref": "#/components/schemas/ProjectView"
            },
            "type": "array"
          }
        },
        "required": [
          "org_id",
          "projects"
        ],
        "type": "object"
      },
      "ProjectMove": {
        "additionalProperties": false,
        "description": "`POST /v1/orgs/{org}/projects/{project}/move`.",
        "properties": {
          "to": {
            "description": "The target organization's id or name.",
            "type": "string"
          }
        },
        "required": [
          "to"
        ],
        "type": "object"
      },
      "ProjectMoved": {
        "description": "`POST /v1/orgs/{org_id}/projects/{project_id}/move` — a project moved to another\norganization, with its snapshots and secrets. Its past runs stay with the organization that\npaid for them, and every key of the project was revoked: mint new ones in the new organization.",
        "properties": {
          "from_org_id": {
            "type": "string"
          },
          "keys_revoked": {
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "project_id": {
            "type": "string"
          },
          "secrets_moved": {
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "snapshots_moved": {
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "to_org_id": {
            "type": "string"
          }
        },
        "required": [
          "project_id",
          "from_org_id",
          "to_org_id",
          "snapshots_moved",
          "secrets_moved",
          "keys_revoked"
        ],
        "type": "object"
      },
      "ProjectPatch": {
        "additionalProperties": false,
        "description": "`PATCH /v1/orgs/{org}/projects/{project}`: at least one field.",
        "properties": {
          "monthly_cap_usd": {
            "description": "A monthly spending cap in USD, 0–1000000; `null` removes the cap.",
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "name": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "type": "object"
      },
      "ProjectView": {
        "description": "One project. API keys belong to a project; a project holds any number of repositories.",
        "properties": {
          "created_at": {
            "description": "RFC 3339.",
            "type": "string"
          },
          "default": {
            "description": "True for the project every organization starts with. It cannot be renamed or deleted.",
            "type": "boolean"
          },
          "keys": {
            "description": "Keys that still work.",
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "month": {
            "description": "The calendar month (UTC, `YYYY-MM`) `month_spend_usd` is for: this month, or the one a\nlist asked for with `?month=`.",
            "type": [
              "string",
              "null"
            ]
          },
          "month_spend_usd": {
            "description": "What this project's runs, data out and builds were billed in `month`, in USD: the same\nfigure its monthly cap is checked against.",
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "monthly_cap_usd": {
            "default": null,
            "description": "The most this project's runs may bill in one calendar month (UTC), in USD; `null` = no\ncap. A run that would pass it is refused with `project_cap_reached`. Set by an owner.",
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "name": {
            "type": "string"
          },
          "org_id": {
            "type": "string"
          },
          "project_id": {
            "type": "string"
          }
        },
        "required": [
          "project_id",
          "org_id",
          "name",
          "default",
          "keys",
          "created_at"
        ],
        "type": "object"
      },
      "Provenance": {
        "properties": {
          "built_at": {
            "description": "RFC 3339.",
            "type": "string"
          },
          "commit": {
            "type": "string"
          },
          "derived_from": {
            "type": [
              "string",
              "null"
            ]
          },
          "dpkg": {
            "description": "`blake3:<hex>` of `dpkg -l`.",
            "type": "string"
          },
          "ecosystem": {
            "type": "string"
          },
          "egress": {
            "items": {
              "$ref": "#/components/schemas/Egress"
            },
            "type": "array"
          },
          "lockfile": {
            "$ref": "#/components/schemas/Lockfile"
          },
          "repo": {
            "type": "string"
          },
          "setup": {
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "sources": {
            "description": "The **additional** pinned repositories cloned into the workspace, in order, before `setup`\nruns. The primary is `repo`/`commit` above and is never repeated here, so a world built\nfrom one repository leaves this empty — and empty means **absent from the JSON**, which\nis what keeps every id computed before the field existed unchanged.\n\nWhy it is in provenance at all: a second repository used to be a `git clone` inside a\n`setup` step, which recorded the command and **not the commit**. The world was still\ncontent-addressed and forkable, but it was not *rebuildable* — the same config produced a\ndifferent world tomorrow and two builds of it stopped deduping. A source with no recorded\ncommit is a reproducibility claim we cannot keep.",
            "items": {
              "$ref": "#/components/schemas/Source"
            },
            "type": "array"
          },
          "toolchain": {
            "additionalProperties": {
              "type": "string"
            },
            "type": "object"
          },
          "verify": {
            "$ref": "#/components/schemas/VerifyCmd"
          }
        },
        "required": [
          "repo",
          "commit",
          "setup",
          "verify",
          "ecosystem",
          "toolchain",
          "lockfile",
          "egress",
          "dpkg",
          "built_at"
        ],
        "type": "object"
      },
      "QueuedReason": {
        "description": "Why a waiting sandbox is waiting. `capacity_arriving`: the sandbox should start within\n`eta_s`. `snapshot_held`: there is no room to start this snapshot right now; the sandbox starts\nas soon as there is. `capacity_limit`: the service is at its capacity limit; the sandbox starts\nwhen room frees, and a smaller `count` needs less of it. `preparing`: the snapshot's first\nstarts take a few seconds; later ones start at once.",
        "enum": [
          "capacity_arriving",
          "snapshot_held",
          "capacity_limit",
          "preparing"
        ],
        "type": "string",
        "x-promigence-open-enum": true
      },
      "Quote": {
        "description": "A quote, per second: `max_cost = Σ sandbox_count × seconds_per_sandbox × per_second_usd`,\nwhere `per_second_usd = vcpus × vcpu_second_usd + mem_gib × gib_second_usd`. The most the run\ncan cost if every sandbox runs its whole timeout; billing is for the seconds actually used.",
        "properties": {
          "breakdown": {
            "items": {
              "$ref": "#/components/schemas/QuoteLine"
            },
            "type": "array"
          },
          "gib_second_usd": {
            "format": "double",
            "type": "number"
          },
          "max_cost": {
            "format": "double",
            "type": "number"
          },
          "mem_gib": {
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "per_second_usd": {
            "format": "double",
            "type": "number"
          },
          "seconds_per_sandbox": {
            "description": "`ceil(timeout_ms / 1000)`: what one full sandbox of this run may bill.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "vcpu_second_usd": {
            "format": "double",
            "type": "number"
          },
          "vcpus": {
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "max_cost",
          "per_second_usd",
          "vcpu_second_usd",
          "gib_second_usd",
          "vcpus",
          "mem_gib",
          "seconds_per_sandbox",
          "breakdown"
        ],
        "type": "object"
      },
      "QuoteEgress": {
        "description": "Data out, as a quote prices it.",
        "properties": {
          "cap_gb_month": {
            "description": "Where data out stops, in GiB per month; `null` when it does not.",
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "gb_usd": {
            "description": "USD per GiB above the included allowance; `null` when the plan sets no rate, in which\ncase data out stops at `cap_gb_month` rather than being billed.",
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "in_max_cost": {
            "description": "Always false: data out is never part of `max_cost`.",
            "type": "boolean"
          },
          "included_gb_month": {
            "description": "GiB included each month; `null` when the plan includes none.",
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "remaining_free_gb": {
            "format": "double",
            "type": "number"
          },
          "used_gb": {
            "format": "double",
            "type": "number"
          }
        },
        "required": [
          "used_gb",
          "remaining_free_gb",
          "in_max_cost"
        ],
        "type": "object"
      },
      "QuoteLine": {
        "properties": {
          "per_second_usd": {
            "format": "double",
            "type": "number"
          },
          "sandbox_count": {
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "seconds_per_sandbox": {
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "sandbox_count",
          "per_second_usd",
          "seconds_per_sandbox"
        ],
        "type": "object"
      },
      "ReferralApplied": {
        "description": "`POST /v1/referrals/apply` — the code, applied.",
        "properties": {
          "code": {
            "type": "string"
          },
          "detail": {
            "description": "Why the code was not applied (`not_applied` only).",
            "type": [
              "string",
              "null"
            ]
          },
          "qualifying_plans": {
            "description": "Plans that invoice qualifies on; empty = any paid plan.",
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "reward_usd": {
            "description": "Compute credit this organization gets when it pays its first plan invoice, USD.",
            "format": "double",
            "type": "number"
          },
          "status": {
            "description": "`pending` (your credit comes with your first paid plan invoice), `under_review`, or — at\nsign-in only — `not_applied`.",
            "type": "string"
          }
        },
        "required": [
          "status",
          "code",
          "reward_usd",
          "qualifying_plans"
        ],
        "type": "object"
      },
      "ReferralApply": {
        "additionalProperties": false,
        "description": "`POST /v1/referrals/apply`.",
        "properties": {
          "code": {
            "description": "The referral code, at most 64 characters.",
            "type": "string"
          }
        },
        "required": [
          "code"
        ],
        "type": "object"
      },
      "ReferralCounts": {
        "description": "Your referrals, counted by status.",
        "properties": {
          "held": {
            "description": "Paid; your credit is on hold.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "other": {
            "description": "Voided, lapsed or not eligible.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "pending": {
            "description": "Signed up, not paid yet.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "rewarded": {
            "description": "Your credit was granted.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "under_review": {
            "description": "Being checked before any credit is granted.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "pending",
          "held",
          "rewarded",
          "under_review",
          "other"
        ],
        "type": "object"
      },
      "ReferralOffer": {
        "description": "A referral offer: \"Give $X, get $Y\".",
        "properties": {
          "credit_expiry_days": {
            "description": "Days the credit lasts from its grant; `null` = it does not expire.",
            "format": "int64",
            "type": [
              "integer",
              "null"
            ]
          },
          "ends_at": {
            "description": "When the offer ends, RFC 3339; `null` = open-ended.",
            "type": [
              "string",
              "null"
            ]
          },
          "get_usd": {
            "description": "Compute credit you get once their payment has cleared the hold, USD.",
            "format": "double",
            "type": "number"
          },
          "give_usd": {
            "description": "Compute credit the friend gets when they pay their first plan invoice, USD.",
            "format": "double",
            "type": "number"
          },
          "headline": {
            "description": "E.g. `\"Give $50, get $100\"`.",
            "type": "string"
          },
          "hold_days": {
            "description": "Days between the friend's payment and your credit.",
            "format": "int64",
            "type": "integer"
          },
          "qualifying_plans": {
            "description": "Plans a first invoice qualifies on; empty = any paid plan.",
            "items": {
              "type": "string"
            },
            "type": "array"
          }
        },
        "required": [
          "headline",
          "give_usd",
          "get_usd",
          "hold_days",
          "qualifying_plans"
        ],
        "type": "object"
      },
      "ReferralStatus": {
        "description": "`GET /v1/referrals` — your referral code and its offer, how your referrals stand, what you\nearned, the referral you came through, and your credit that expires.",
        "properties": {
          "code": {
            "description": "Your code: a friend signs up with `promigence login --ref <code>`. `null` while the program\nis off.",
            "type": [
              "string",
              "null"
            ]
          },
          "earned_usd": {
            "description": "Credit your referrals have earned you, USD.",
            "format": "double",
            "type": "number"
          },
          "expiring_credits": {
            "description": "Credit that expires, soonest first, with what is left of each grant.",
            "items": {
              "$ref": "#/components/schemas/ExpiringCredit"
            },
            "type": "array"
          },
          "offer": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ReferralOffer"
              },
              {
                "type": "null"
              }
            ],
            "description": "What your code offers now. `null` while the program is off."
          },
          "program": {
            "description": "`\"on\"` while an offer runs, else `\"off\"` (no code is handed out then).",
            "type": "string"
          },
          "referrals": {
            "$ref": "#/components/schemas/ReferralCounts",
            "description": "Your referrals by status (counts only)."
          },
          "referred_by": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ReferredBy"
              },
              {
                "type": "null"
              }
            ],
            "description": "The referral this organization came through, if any."
          }
        },
        "required": [
          "program",
          "referrals",
          "earned_usd",
          "expiring_credits"
        ],
        "type": "object"
      },
      "ReferredBy": {
        "description": "The referral an organization came through.",
        "properties": {
          "reward_usd": {
            "description": "Compute credit this organization gets (or got) when it pays its first plan invoice, USD.",
            "format": "double",
            "type": "number"
          },
          "rewarded_at": {
            "description": "When that credit was granted; `null` until then.",
            "type": [
              "string",
              "null"
            ]
          },
          "status": {
            "description": "`pending` | `held` | `rewarded` | `under_review` | `voided` | `lapsed` | `not_eligible`.",
            "type": "string"
          }
        },
        "required": [
          "status",
          "reward_usd"
        ],
        "type": "object"
      },
      "ReplayRef": {
        "description": "One newly forked replay. It is a **new sandbox with its own id**, not the failed one\nrestarted; `replay_of` names what it stands in for.",
        "properties": {
          "replay_of": {
            "type": "string"
          },
          "sandbox_id": {
            "type": "string"
          },
          "state": {
            "description": "`\"queued\"`.",
            "type": "string"
          }
        },
        "required": [
          "sandbox_id",
          "replay_of",
          "state"
        ],
        "type": "object"
      },
      "ReplayStats": {
        "properties": {
          "n": {
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "success_pct": {
            "format": "double",
            "type": "number"
          }
        },
        "required": [
          "n",
          "success_pct"
        ],
        "type": "object"
      },
      "Requested": {
        "properties": {
          "allow_partial": {
            "type": "boolean"
          },
          "count": {
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "grade": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/GradeSpec"
              },
              {
                "type": "null"
              }
            ],
            "description": "The `grade` block this run was created with, echoed back."
          },
          "grade_output": {
            "description": "The run asked for the grader's own output (`grade_output`): each graded sandbox's\n`grade.output`.",
            "type": "boolean"
          },
          "network": {
            "$ref": "#/components/schemas/Network"
          },
          "secrets": {
            "default": [],
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "timeout_ms": {
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "verify_each": {
            "type": "boolean"
          }
        },
        "required": [
          "count",
          "timeout_ms",
          "verify_each",
          "network",
          "allow_partial"
        ],
        "type": "object"
      },
      "Run": {
        "properties": {
          "alias": {
            "type": [
              "string",
              "null"
            ]
          },
          "cost": {
            "$ref": "#/components/schemas/Cost"
          },
          "finished_at": {
            "type": [
              "string",
              "null"
            ]
          },
          "fork": {
            "$ref": "#/components/schemas/ForkStats"
          },
          "grade": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/GradeStats"
              },
              {
                "type": "null"
              }
            ],
            "description": "The two pass rates and the **gap** between them. Absent when the run was not graded."
          },
          "labels": {
            "additionalProperties": {
              "type": "string"
            },
            "default": {},
            "type": "object"
          },
          "quote": {
            "$ref": "#/components/schemas/Quote"
          },
          "requested": {
            "$ref": "#/components/schemas/Requested"
          },
          "run_id": {
            "type": "string"
          },
          "sandboxes": {
            "items": {
              "$ref": "#/components/schemas/Sandbox"
            },
            "type": "array"
          },
          "schema": {
            "type": "string"
          },
          "snapshot_id": {
            "type": "string"
          },
          "spend_cap": {
            "format": "double",
            "type": "number"
          },
          "started_at": {
            "type": "string"
          },
          "state": {
            "$ref": "#/components/schemas/RunState"
          },
          "totals": {
            "$ref": "#/components/schemas/Totals"
          }
        },
        "required": [
          "schema",
          "run_id",
          "state",
          "snapshot_id",
          "requested",
          "quote",
          "spend_cap",
          "started_at",
          "fork",
          "totals",
          "cost",
          "sandboxes"
        ],
        "type": "object"
      },
      "RunCanceled": {
        "description": "`POST /v1/runs/{id}/cancel` — what was still queued is now stopped. Live sandboxes keep\nrunning; `DELETE /v1/runs/{id}` is for those.",
        "properties": {
          "canceled": {
            "description": "How many queued sandboxes were dropped. They were never started, so they are not billed.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "ok": {
            "type": "boolean"
          },
          "run_id": {
            "type": "string"
          }
        },
        "required": [
          "ok",
          "run_id",
          "canceled"
        ],
        "type": "object"
      },
      "RunCreate": {
        "additionalProperties": false,
        "description": "`POST /v1/runs`: start `count` sandboxes from a snapshot.",
        "properties": {
          "allow_partial": {
            "description": "Start what fits now rather than refusing the whole run.",
            "type": "boolean"
          },
          "capture": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/CaptureMode"
              },
              {
                "type": "null"
              }
            ]
          },
          "count": {
            "description": "How many sandboxes, 1–1000.",
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "exec": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ExecCreate"
              },
              {
                "type": "null"
              }
            ],
            "description": "A command each sandbox runs as it starts; the sandbox's outcome is its exit."
          },
          "grade": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/GradeSpec"
              },
              {
                "type": "null"
              }
            ],
            "description": "Score each sandbox's work after its command."
          },
          "grade_output": {
            "description": "Keep what the grader prints: the last 16 KiB of its output, stdout and stderr together, in\neach graded sandbox's `grade.output` in the run report. Never a held-out grader's. Absent:\nthe setting of the snapshot's default grader when the run uses it, otherwise off. Needs a\ngrader (`grade`, or the snapshot's default).",
            "type": [
              "boolean",
              "null"
            ]
          },
          "labels": {
            "additionalProperties": {
              "type": "string"
            },
            "description": "Your own key/value labels, returned on every answer about the run.",
            "type": "object"
          },
          "network": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/NetworkRequest"
              },
              {
                "type": "null"
              }
            ]
          },
          "optimize_for": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/OptimizeFor"
              },
              {
                "type": "null"
              }
            ]
          },
          "preemptible": {
            "description": "The lower batch rate: the run's sandboxes can be stopped early.",
            "type": "boolean"
          },
          "secrets": {
            "description": "Stored secrets every command in the run's sandboxes receives.",
            "items": {
              "$ref": "#/components/schemas/SecretUse"
            },
            "type": "array"
          },
          "snapshot": {
            "description": "A snapshot id, alias, `alias@commit7`, or `promigence/base`.",
            "type": "string"
          },
          "spend_cap": {
            "description": "The most the run may cost, in USD.",
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "tier": {
            "description": "The sandbox size. Default: the snapshot's.",
            "type": [
              "string",
              "null"
            ]
          },
          "timeout_ms": {
            "description": "Each sandbox's lifetime in milliseconds. Default 15 minutes, at most 30 days.",
            "format": "uint64",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "verify_each": {
            "description": "Re-run the snapshot's verification in each sandbox before it takes work.",
            "type": "boolean"
          }
        },
        "required": [
          "snapshot",
          "count"
        ],
        "type": "object"
      },
      "RunCreated": {
        "description": "`POST /v1/runs` — the run, and every sandbox it started.",
        "properties": {
          "count": {
            "description": "How many sandboxes were asked for.",
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "idempotent_replay": {
            "description": "True when this is the stored answer to an `Idempotency-Key` that was seen before, and no\nsecond run was started.",
            "type": "boolean"
          },
          "idempotent_replay_age_s": {
            "description": "Present when `idempotent_replay` is true: how many seconds ago that first answer was\ngiven, so a client can say which earlier request this repeats.",
            "format": "uint64",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "launched": {
            "description": "How many were started. Fewer than `count` only with `allow_partial`, and the reason is in\n`warnings`.",
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "preemptible": {
            "description": "True when the run was posted at the preemptible rate: its sandboxes can be stopped early,\nand one stopped that way bills nothing.",
            "type": "boolean"
          },
          "quote": {
            "$ref": "#/components/schemas/Quote"
          },
          "run_id": {
            "type": "string"
          },
          "sandboxes": {
            "items": {
              "$ref": "#/components/schemas/RunSandboxRef"
            },
            "type": "array"
          },
          "snapshot": {
            "description": "The snapshot, resolved.",
            "type": "string"
          },
          "snapshot_arg": {
            "description": "The snapshot as you named it — an id, an alias, or a path.",
            "type": "string"
          },
          "snapshot_id": {
            "description": "The snapshot's id, as `GET /v1/runs/{id}` and the report give it: `\"\"` for the built-in\nbase. Never `null` from this API; typed nullable for older answers.",
            "type": [
              "string",
              "null"
            ]
          },
          "spend_cap": {
            "description": "The most this run may cost, in USD.",
            "format": "double",
            "type": "number"
          },
          "state": {
            "description": "`\"running\"`.",
            "type": "string"
          },
          "tier": {
            "type": "string"
          },
          "timeout_ms": {
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "warnings": {
            "description": "What was **not** started and why, said when it is decided rather than discovered in the\nreport.",
            "items": {
              "type": "string"
            },
            "type": "array"
          }
        },
        "required": [
          "run_id",
          "state",
          "snapshot",
          "snapshot_arg",
          "count",
          "launched",
          "timeout_ms",
          "tier",
          "preemptible",
          "spend_cap",
          "quote",
          "sandboxes",
          "warnings",
          "idempotent_replay"
        ],
        "type": "object"
      },
      "RunKilled": {
        "description": "`DELETE /v1/runs/{id}` — the queue is cancelled and every live sandbox is killed.",
        "properties": {
          "killed": {
            "description": "How many live sandboxes were killed. Each is billed for the seconds it used.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "ok": {
            "type": "boolean"
          },
          "run_id": {
            "type": "string"
          }
        },
        "required": [
          "ok",
          "run_id",
          "killed"
        ],
        "type": "object"
      },
      "RunList": {
        "description": "`GET /v1/runs`.",
        "properties": {
          "next_cursor": {
            "default": null,
            "description": "Pass as `?cursor=` for the next page; `null` on the last one.",
            "type": [
              "string",
              "null"
            ]
          },
          "runs": {
            "items": {
              "$ref": "#/components/schemas/RunView"
            },
            "type": "array"
          }
        },
        "required": [
          "runs"
        ],
        "type": "object"
      },
      "RunOpen": {
        "additionalProperties": false,
        "description": "`POST /v1/runs/{id}/open`: reopen a captured failure as a live sandbox.",
        "properties": {
          "sandbox_id": {
            "description": "Which captured sandbox; required when the run has more than one capture.",
            "type": [
              "string",
              "null"
            ]
          },
          "spend_cap": {
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "timeout_ms": {
            "format": "uint64",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          }
        },
        "type": "object"
      },
      "RunOpened": {
        "description": "`POST /v1/runs/{id}/open` — a preserved failure, handed back as a **new, live sandbox** with\nits own id and its own billing clock. Not a replay: the state is the one the sandbox was in\nwhen it broke.",
        "properties": {
          "code": {
            "description": "The original's failure code.",
            "type": "string"
          },
          "committed_seconds": {
            "description": "Billable seconds committed to the new sandbox.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "detail": {
            "type": "string"
          },
          "expires_at": {
            "description": "When the preserved state expires, RFC 3339.",
            "type": "string"
          },
          "failed_at": {
            "description": "When the original failed, RFC 3339.",
            "type": "string"
          },
          "max_cost": {
            "description": "The most the new sandbox may cost, in USD.",
            "format": "double",
            "type": "number"
          },
          "ok": {
            "type": "boolean"
          },
          "opened_from": {
            "description": "The failed sandbox this one was opened from.",
            "type": "string"
          },
          "outcome": {
            "description": "The original's outcome.",
            "type": "string"
          },
          "ready_ms": {
            "description": "Milliseconds until it was ready.",
            "format": "double",
            "type": "number"
          },
          "run_id": {
            "type": "string"
          },
          "sandbox_id": {
            "description": "The new sandbox.",
            "type": "string"
          },
          "snapshot_id": {
            "description": "The preserved state it was opened from.",
            "type": "string"
          },
          "state": {
            "description": "`\"ready\"`.",
            "type": "string"
          },
          "timeout_ms": {
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "ok",
          "run_id",
          "sandbox_id",
          "state",
          "ready_ms",
          "opened_from",
          "snapshot_id",
          "failed_at",
          "outcome",
          "code",
          "expires_at",
          "committed_seconds",
          "timeout_ms",
          "max_cost",
          "detail"
        ],
        "type": "object"
      },
      "RunQuote": {
        "description": "The price a run was quoted at, frozen when it started.\n\nThe same numbers `POST /v1/runs/quote` answers with, without the per-line breakdown: a run\nthat exists has one line.",
        "properties": {
          "gib_second_usd": {
            "format": "double",
            "type": "number"
          },
          "max_cost": {
            "description": "The most the run can cost if every sandbox runs its whole timeout, in USD. Billing is for\nthe seconds actually used.",
            "format": "double",
            "type": "number"
          },
          "mem_gib": {
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "per_second_usd": {
            "format": "double",
            "type": "number"
          },
          "seconds_per_sandbox": {
            "description": "`ceil(timeout_ms / 1000)`: what one full sandbox of this run may bill.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "vcpu_second_usd": {
            "format": "double",
            "type": "number"
          },
          "vcpus": {
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "max_cost",
          "per_second_usd",
          "vcpu_second_usd",
          "gib_second_usd",
          "vcpus",
          "mem_gib",
          "seconds_per_sandbox"
        ],
        "type": "object"
      },
      "RunQuoteRequest": {
        "additionalProperties": false,
        "description": "`POST /v1/runs/quote`: the price of a run before it starts.",
        "properties": {
          "count": {
            "description": "1–1000.",
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "preemptible": {
            "type": "boolean"
          },
          "snapshot": {
            "type": "string"
          },
          "spend_cap": {
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "tier": {
            "type": [
              "string",
              "null"
            ]
          },
          "timeout_ms": {
            "format": "uint64",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          }
        },
        "required": [
          "snapshot",
          "count"
        ],
        "type": "object"
      },
      "RunQuoteView": {
        "description": "`POST /v1/runs/quote` — what a run would cost, before anything starts. Nothing is reserved.",
        "properties": {
          "billing": {
            "description": "`per_second`.",
            "type": "string"
          },
          "breakdown": {
            "items": {
              "$ref": "#/components/schemas/QuoteLine"
            },
            "type": "array"
          },
          "count": {
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "credits_available": {
            "description": "Trial credits available, in USD; `null` when the organisation is not on a trial.",
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "egress": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/QuoteEgress"
              },
              {
                "type": "null"
              }
            ],
            "description": "Data out, priced beside compute: the rate, what the month includes and what is left of\nit. `max_cost` does not cover it. `null` when the organisation's plan could not be read."
          },
          "gib_second_usd": {
            "format": "double",
            "type": "number"
          },
          "granularity_seconds": {
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "max_cost": {
            "description": "The most the run can cost if every sandbox runs its whole timeout, in USD.",
            "format": "double",
            "type": "number"
          },
          "mem_gib": {
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "min_billable_seconds": {
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "per_hour_usd": {
            "format": "double",
            "type": "number"
          },
          "per_second_usd": {
            "format": "double",
            "type": "number"
          },
          "preemptible": {
            "type": "boolean"
          },
          "quote": {
            "$ref": "#/components/schemas/Quote",
            "description": "The same quote, whole — what `POST /v1/runs` and the report echo back."
          },
          "seconds_per_sandbox": {
            "description": "`ceil(timeout_ms / 1000)`: what one full sandbox may bill.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "snapshot": {
            "description": "The snapshot as you named it.",
            "type": "string"
          },
          "snapshot_id": {
            "description": "`null` for a snapshot this service holds no record of.",
            "type": [
              "string",
              "null"
            ]
          },
          "spend_cap": {
            "description": "The cap the run would be held to: the one you passed, or the organisation's default.",
            "format": "double",
            "type": "number"
          },
          "tier": {
            "type": "string"
          },
          "timeout_ms": {
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "vcpu_second_usd": {
            "format": "double",
            "type": "number"
          },
          "vcpus": {
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "warnings": {
            "description": "Anything that would make `POST /v1/runs` refuse this, said now.",
            "items": {
              "type": "string"
            },
            "type": "array"
          }
        },
        "required": [
          "snapshot",
          "count",
          "timeout_ms",
          "tier",
          "preemptible",
          "billing",
          "granularity_seconds",
          "min_billable_seconds",
          "vcpus",
          "mem_gib",
          "vcpu_second_usd",
          "gib_second_usd",
          "per_second_usd",
          "per_hour_usd",
          "seconds_per_sandbox",
          "max_cost",
          "breakdown",
          "quote",
          "spend_cap",
          "warnings"
        ],
        "type": "object"
      },
      "RunReplay": {
        "additionalProperties": false,
        "description": "`POST /v1/runs/{id}/replay`.",
        "properties": {
          "env": {
            "additionalProperties": {
              "type": "string"
            },
            "description": "Values for the environment variables the run's command was started with. A run keeps\ntheir names, never their values, so a replay of a command that had any needs every one.",
            "type": "object"
          },
          "sandbox_ids": {
            "description": "The sandboxes to replay; omitted, every one that may be replayed.",
            "items": {
              "type": "string"
            },
            "type": [
              "array",
              "null"
            ]
          }
        },
        "type": "object"
      },
      "RunReplayed": {
        "description": "`POST /v1/runs/{id}/replay` — the environment failures, re-forked.",
        "properties": {
          "detail": {
            "description": "Present only when there was nothing to replay, saying so.",
            "type": [
              "string",
              "null"
            ]
          },
          "ok": {
            "type": "boolean"
          },
          "replayed": {
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "run_id": {
            "type": "string"
          },
          "sandboxes": {
            "items": {
              "$ref": "#/components/schemas/ReplayRef"
            },
            "type": "array"
          }
        },
        "required": [
          "ok",
          "run_id",
          "replayed",
          "sandboxes"
        ],
        "type": "object"
      },
      "RunSandboxRef": {
        "description": "One sandbox of a run, in the compact form the run routes carry.\n\nSome fields are absent rather than null in some answers, because the route that writes them\ndoes not always know them yet: a sandbox that has not started has no committed seconds\nto report, and one refused by the spend cap never will.",
        "properties": {
          "command_outcome": {
            "description": "The verdict on the sandbox's terminal command when the sandbox outlived it: `completed` |\n`task_failed` when the command asked to keep it (`kill_on_exit: false`), the sandbox still\nlive and billed until it is ended or expires; `cap_killed` when the run's spend cap (or\nthe trial's credits) stopped the command and the sandbox was paused with its files and\nstate (`pause_reason` on the sandbox), to go on once the cap is raised or credits are\nadded. Absent otherwise; a sandbox that ended with its command carries the verdict in\n`outcome`.",
            "type": [
              "string",
              "null"
            ]
          },
          "committed_seconds": {
            "description": "Billable seconds committed to this sandbox.",
            "format": "uint64",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "eta_s": {
            "description": "Seconds until this sandbox is expected to start, with\n`queued_reason: capacity_arriving`. `null` with the other reasons, and once the sandbox has\nwaited longer than the estimate it was first given; `queued_message` then says it is\ntaking longer than expected rather than repeating a number.",
            "format": "uint64",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "one_time": {
            "description": "True when this is a one-time wait: once the waiting sandboxes can start, the rest of the\nrun starts at once too. False otherwise.",
            "type": [
              "boolean",
              "null"
            ]
          },
          "outcome": {
            "description": "Why it ended.",
            "type": [
              "string",
              "null"
            ]
          },
          "queued_message": {
            "description": "The same, in words, ready to show a person.",
            "type": [
              "string",
              "null"
            ]
          },
          "queued_reason": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/QueuedReason"
              },
              {
                "type": "null"
              }
            ]
          },
          "replay_of": {
            "description": "The sandbox this one is a replay of.",
            "type": [
              "string",
              "null"
            ]
          },
          "sandbox_id": {
            "type": "string"
          },
          "state": {
            "description": "`queued` | `awaiting_capacity` | `ready` | `running` | `paused` | `ended`.",
            "type": "string"
          }
        },
        "required": [
          "sandbox_id",
          "state"
        ],
        "type": "object"
      },
      "RunSandboxes": {
        "description": "`GET /v1/runs/{id}/sandboxes` — the full records, and whether the waiting ones can start.",
        "properties": {
          "capacity": {
            "$ref": "#/components/schemas/Capacity"
          },
          "run_id": {
            "type": "string"
          },
          "sandboxes": {
            "items": {
              "$ref": "#/components/schemas/SandboxView"
            },
            "type": "array"
          }
        },
        "required": [
          "run_id",
          "sandboxes",
          "capacity"
        ],
        "type": "object"
      },
      "RunState": {
        "enum": [
          "running",
          "completed",
          "cap_killed",
          "aborted"
        ],
        "type": "string",
        "x-promigence-open-enum": true
      },
      "RunView": {
        "description": "One run, as `GET /v1/runs/{id}` and the rows of `GET /v1/runs` report it.",
        "properties": {
          "canceled": {
            "type": "boolean"
          },
          "capacity": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Capacity"
              },
              {
                "type": "null"
              }
            ],
            "description": "Only on `GET /v1/runs/{id}`: whether the waiting sandboxes can start, so a client that is already\nlong-polling this route does not need a second call to find out why it is waiting."
          },
          "capture": {
            "description": "What this run does with a sandbox's state when it ends: `on_failure` | `off` | `always`.\nStated on every answer, so nobody has to remember what the default was.",
            "type": "string"
          },
          "count": {
            "description": "How many sandboxes were asked for.",
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "counts": {
            "additionalProperties": {
              "format": "uint64",
              "minimum": 0,
              "type": "integer"
            },
            "description": "How many sandboxes are in each state, keyed by state or by outcome. Only on\n`GET /v1/runs/{id}`.",
            "type": [
              "object",
              "null"
            ]
          },
          "exec": {
            "description": "The command each sandbox was created with, if any."
          },
          "finished_at": {
            "description": "RFC 3339; `null` while the run is still going.",
            "type": [
              "string",
              "null"
            ]
          },
          "grade": {
            "description": "The grading block this run was submitted with, if any."
          },
          "grade_output": {
            "description": "The run keeps what its grader prints (`grade_output`). Absent when it does not.",
            "type": "boolean"
          },
          "labels": {
            "additionalProperties": {
              "type": "string"
            },
            "type": "object"
          },
          "network": {
            "description": "The policy as it was submitted: `\"egress\"` / `\"none\"` stay strings, an allowlist comes\nback as the object you sent, normalised."
          },
          "quote": {
            "$ref": "#/components/schemas/RunQuote"
          },
          "run_id": {
            "type": "string"
          },
          "sandboxes": {
            "description": "Only on `GET /v1/runs/{id}`: one compact row per sandbox. The full records, with their\ntimings, are `GET /v1/runs/{id}/sandboxes`.",
            "items": {
              "$ref": "#/components/schemas/RunSandboxRef"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "snapshot": {
            "description": "The snapshot this run forks from, as it was asked for.",
            "type": "string"
          },
          "snapshot_id": {
            "description": "The same value under the name the validity report uses. Both are sent so a client can\nread either.",
            "type": "string"
          },
          "spend_cap": {
            "description": "The most this run may cost, in USD.",
            "format": "double",
            "type": "number"
          },
          "started_at": {
            "description": "RFC 3339.",
            "type": "string"
          },
          "state": {
            "description": "`queued` | `running` | `completed` | `aborted`.",
            "type": "string"
          },
          "tier": {
            "type": "string"
          },
          "timeout_ms": {
            "description": "Each sandbox's lifetime, in milliseconds.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "verify_each": {
            "description": "Whether each sandbox re-ran the snapshot's own verification before taking work.",
            "type": "boolean"
          }
        },
        "required": [
          "run_id",
          "state",
          "snapshot",
          "snapshot_id",
          "count",
          "timeout_ms",
          "tier",
          "spend_cap",
          "quote",
          "verify_each",
          "network",
          "capture",
          "labels",
          "canceled",
          "started_at"
        ],
        "type": "object"
      },
      "Sandbox": {
        "description": "Why a waiting sandbox is waiting and how long that should take, when it is known. All four\nfields are absent while the sandbox is not waiting, and while nothing more is known than that\nit is queued; when `queued_reason` is present, so are the other three.",
        "properties": {
          "attempt": {
            "format": "uint8",
            "maximum": 255,
            "minimum": 0,
            "type": "integer"
          },
          "billable_seconds": {
            "default": 0,
            "description": "What the ledger bills for this sandbox: `min(used, committed)` for a billed outcome, and\nfor an `env_failed` that only the sandbox could explain (it stopped responding, or only its\nown copy changed); 0 for an `env_failed` confirmed on our side and for `not_started` /\n`superseded` / `preempted`.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "capture": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Capture"
              },
              {
                "type": "null"
              }
            ],
            "description": "What was preserved of this sandbox when it ended, and when it expires. Absent when\nnothing was kept (`capture: \"off\"`, a success under the default, or a sandbox that ended\nbefore its state could be captured)."
          },
          "committed_seconds": {
            "default": 0,
            "description": "The cap: the seconds this sandbox was allowed to bill (`POST /runs` quote, raised only by\n`PATCH /sandboxes/:id`). Printed because it is the right-hand side of the invariant\n`billable_seconds <= committed_seconds` — without it the reader has to take our word.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "cost": {
            "default": 0,
            "description": "`billable_seconds × per_second_usd`, USD.",
            "format": "double",
            "type": "number"
          },
          "e2e_ms": {
            "description": "From the start request, after any time queued, to the hand-over: not `queued_ms`.",
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "env_verified": {
            "type": "boolean"
          },
          "eta_s": {
            "description": "Seconds until this sandbox is expected to start, with\n`queued_reason: capacity_arriving`. `null` with the other reasons, and once the sandbox has\nwaited longer than the estimate it was first given; `queued_message` then says it is\ntaking longer than expected rather than repeating a number.",
            "format": "uint64",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "execs": {
            "default": [],
            "items": {
              "$ref": "#/components/schemas/ExecRecord"
            },
            "type": "array"
          },
          "failure": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Failure"
              },
              {
                "type": "null"
              }
            ]
          },
          "grade": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/GradeOutput"
              },
              {
                "type": "null"
              }
            ],
            "description": "What the grader printed, when the run asked for it (`grade_output`). Absent otherwise."
          },
          "graded": {
            "description": "The grader ran in a fresh fork and produced a verdict.",
            "type": "boolean"
          },
          "holdout_passed": {
            "description": "The customer's held-out set, run in its own fresh fork. Reported, never attributed: a\nheld-out failure is the number we sell, not a reason to fail the sandbox.",
            "type": [
              "boolean",
              "null"
            ]
          },
          "holdout_score": {
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "one_time": {
            "description": "True when this is a one-time wait: once the waiting sandboxes can start, the rest of the\nrun starts at once too. False otherwise.",
            "type": [
              "boolean",
              "null"
            ]
          },
          "opened_from": {
            "description": "`POST /v1/runs/:id/open`: this sandbox was forked from the named sandbox's failure\ncapture. A NEW sandbox with its own billing clock, not the dead one resurrected — and,\nlike a replay, held out of the run's success percentages.",
            "type": [
              "string",
              "null"
            ]
          },
          "outcome": {
            "$ref": "#/components/schemas/Outcome"
          },
          "passed": {
            "description": "The visible test set's verdict. This one decides the sandbox's outcome.",
            "type": [
              "boolean",
              "null"
            ]
          },
          "queued_message": {
            "description": "The same, in words, ready to show a person.",
            "type": [
              "string",
              "null"
            ]
          },
          "queued_ms": {
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "queued_reason": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/QueuedReason"
              },
              {
                "type": "null"
              }
            ]
          },
          "ready_ms": {
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "replay_of": {
            "type": [
              "string",
              "null"
            ]
          },
          "retry_of": {
            "type": [
              "string",
              "null"
            ]
          },
          "sandbox_id": {
            "type": "string"
          },
          "score": {
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "state": {
            "$ref": "#/components/schemas/SandboxState"
          },
          "t_end": {
            "type": [
              "string",
              "null"
            ]
          },
          "t_handoff": {
            "type": [
              "string",
              "null"
            ]
          },
          "used_seconds": {
            "default": 0,
            "description": "`(t_end − t_handoff) − paused`, rounded up to the granularity: the seconds this sandbox\nran, whatever the outcome.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "verify_each_ms": {
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "warm_measured": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/WarmMeasured"
              },
              {
                "type": "null"
              }
            ]
          },
          "warnings": {
            "default": [],
            "items": {
              "type": "string"
            },
            "type": "array"
          }
        },
        "required": [
          "sandbox_id",
          "state",
          "attempt",
          "env_verified",
          "outcome"
        ],
        "type": "object"
      },
      "SandboxExtended": {
        "description": "The sandbox's new lifetime and what it costs.",
        "properties": {
          "committed_seconds": {
            "description": "Billable seconds now committed to this sandbox.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "cost": {
            "$ref": "#/components/schemas/ExtensionCost"
          },
          "ok": {
            "type": "boolean"
          },
          "run_id": {
            "type": "string"
          },
          "sandbox_id": {
            "type": "string"
          },
          "timeout_ms": {
            "description": "The sandbox's total lifetime after the change, in milliseconds. This is the total, not an\noffset from now.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "ok",
          "sandbox_id",
          "run_id",
          "timeout_ms",
          "committed_seconds",
          "cost"
        ],
        "type": "object"
      },
      "SandboxKilled": {
        "description": "`DELETE /v1/sandboxes/{id}`.",
        "properties": {
          "already_ended": {
            "description": "True when the sandbox had already ended and this call changed nothing.",
            "type": "boolean"
          },
          "ok": {
            "type": "boolean"
          },
          "outcome": {
            "type": [
              "string",
              "null"
            ]
          },
          "sandbox_id": {
            "type": "string"
          },
          "state": {
            "description": "`\"ended\"`.",
            "type": "string"
          }
        },
        "required": [
          "ok",
          "sandbox_id",
          "state",
          "already_ended"
        ],
        "type": "object"
      },
      "SandboxList": {
        "description": "`GET /v1/sandboxes` — one page, newest first.",
        "properties": {
          "labels": {
            "additionalProperties": {
              "type": "string"
            },
            "description": "The label filter this list was produced with; empty when none was given.",
            "type": "object"
          },
          "limit": {
            "description": "The page size that was applied.",
            "format": "int64",
            "type": "integer"
          },
          "next_cursor": {
            "description": "Pass back as `?cursor=` for the next page; `null` on the last page. A short page is not\nthe end: a filter can empty a page that still has more behind it.",
            "type": [
              "string",
              "null"
            ]
          },
          "sandboxes": {
            "items": {
              "$ref": "#/components/schemas/SandboxView"
            },
            "type": "array"
          },
          "state": {
            "description": "The state filter this list was produced with; empty when none was given. `queued` keeps\nevery waiting sandbox; `awaiting_capacity` only those waiting for capacity being added.",
            "items": {
              "type": "string"
            },
            "type": "array"
          }
        },
        "required": [
          "sandboxes",
          "labels",
          "state",
          "limit"
        ],
        "type": "object"
      },
      "SandboxNetwork": {
        "description": "`GET /v1/sandboxes/{id}/network` — what this sandbox may reach, and what it asked for and was\nrefused.",
        "properties": {
          "network": {
            "description": "`\"egress\"`, `\"none\"`, or `{\"allow\": [...]}` — the policy in force: as it was written, or\n`\"none\"` once the sandbox's egress has been cut."
          },
          "refused_connections": {
            "description": "Connections refused, counted, including those to a bare address (which have no name to\nlist and whose addresses are not recorded). Only for a sandbox that is still running."
          },
          "refused_hosts": {
            "description": "The hosts this sandbox was refused, by name. Current while it is\nrunning, and as recorded once it is not. A connection to a bare\naddress has no name: it is counted in `refused_connections`, not listed here."
          },
          "refused_lookups": {
            "description": "Name lookups refused. Only for a sandbox that is still running."
          },
          "sandbox_id": {
            "type": "string"
          },
          "state": {
            "type": "string"
          },
          "via_secret": {
            "description": "The hosts this sandbox may reach for its host-bound secrets (`secrets set --host`), each\nsecret by name with its hosts, whatever `network` says. Absent when it has none.",
            "items": {
              "$ref": "#/components/schemas/ViaSecret"
            },
            "type": "array"
          }
        },
        "required": [
          "sandbox_id",
          "network",
          "state",
          "refused_hosts"
        ],
        "type": "object"
      },
      "SandboxNetworkCut": {
        "description": "`POST /v1/sandboxes/{id}/network` — the answer to cutting a live sandbox's egress.",
        "properties": {
          "applied": {
            "description": "False if the sandbox was already running with no egress.",
            "type": "boolean"
          },
          "network": {
            "$ref": "#/components/schemas/NetworkMode"
          },
          "sandbox_id": {
            "type": "string"
          },
          "state": {
            "type": "string"
          }
        },
        "required": [
          "sandbox_id",
          "network",
          "applied",
          "state"
        ],
        "type": "object"
      },
      "SandboxNetworkSet": {
        "additionalProperties": false,
        "description": "`POST /v1/sandboxes/{id}/network`: cut a running sandbox's network.",
        "properties": {
          "network": {
            "description": "`none`, the only value.",
            "type": "string"
          }
        },
        "required": [
          "network"
        ],
        "type": "object"
      },
      "SandboxPatch": {
        "additionalProperties": false,
        "description": "`PATCH /v1/sandboxes/{id}`: a new lifetime, a new idle rule, or both.",
        "properties": {
          "auto_pause_mode": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/AutoPauseMode"
              },
              {
                "type": "null"
              }
            ]
          },
          "auto_pause_s": {
            "description": "Pause after this many idle seconds; 0 turns the rule off.",
            "format": "uint64",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "timeout_ms": {
            "description": "The new lifetime in milliseconds, counted from now.",
            "format": "uint64",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          }
        },
        "type": "object"
      },
      "SandboxPatched": {
        "anyOf": [
          {
            "$ref": "#/components/schemas/AutoPauseSet"
          },
          {
            "$ref": "#/components/schemas/SandboxExtended"
          }
        ],
        "description": "`PATCH /v1/sandboxes/{id}` — one of two answers, by what was sent: the idle rule alone\n([`AutoPauseSet`]), or a new lifetime ([`SandboxExtended`], also when both were sent)."
      },
      "SandboxPaused": {
        "description": "`POST /v1/sandboxes/{id}/pause`.",
        "properties": {
          "already_paused": {
            "description": "Present, and true, only when the sandbox was already paused and this call changed nothing.\nThe fields below it are then absent.",
            "type": [
              "boolean",
              "null"
            ]
          },
          "background_execs_killed": {
            "description": "Background commands the pause ended, when there were any. A pause does not keep a\nrunning background command: start it again after resume.",
            "format": "uint32",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "bytes": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ParkedBytes"
              },
              {
                "type": "null"
              }
            ],
            "description": "What the parked sandbox occupies on disk while it is not running."
          },
          "durable": {
            "description": "True when the parked state is kept safe from a failure on our side. `false` is not an\nerror.",
            "type": [
              "boolean",
              "null"
            ]
          },
          "ok": {
            "type": "boolean"
          },
          "paused_id": {
            "description": "An opaque name for this pause. Resume by the sandbox id; this one is for your records.",
            "type": [
              "string",
              "null"
            ]
          },
          "recorded": {
            "description": "False if the sandbox was parked but the change could not be written down, which is worth\nretrying.",
            "type": [
              "boolean",
              "null"
            ]
          },
          "sandbox_id": {
            "type": "string"
          },
          "state": {
            "description": "`\"paused\"`.",
            "type": "string"
          },
          "took_ms": {
            "description": "Milliseconds the pause took, from the request to the answer.",
            "format": "uint64",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "warnings": {
            "description": "Things to know about what was parked, one `code: sentence` per line; only when there is\none. Today the only one is `secrets_in_saved_state`.",
            "items": {
              "type": "string"
            },
            "type": [
              "array",
              "null"
            ]
          }
        },
        "required": [
          "ok",
          "sandbox_id",
          "state"
        ],
        "type": "object"
      },
      "SandboxProbe": {
        "description": "`POST /v1/sandboxes/{id}/probe` — the files re-checked against the verified snapshot.",
        "properties": {
          "checked": {
            "description": "What was checked: the list you asked for, or the string `\"verified_paths\"` for the\nsnapshot's own recorded set."
          },
          "first_bad_path": {
            "description": "The first path that differs, and the only part of a failed check anyone can act on.",
            "type": [
              "string",
              "null"
            ]
          },
          "ms": {
            "description": "How long the check took, in milliseconds.",
            "format": "double",
            "type": "number"
          },
          "ok": {
            "description": "True when every path checked still matches what was verified.",
            "type": "boolean"
          },
          "sandbox_id": {
            "type": "string"
          }
        },
        "required": [
          "sandbox_id",
          "ok",
          "ms",
          "checked"
        ],
        "type": "object"
      },
      "SandboxProbeRequest": {
        "additionalProperties": false,
        "description": "`POST /v1/sandboxes/{id}/probe`.",
        "properties": {
          "paths": {
            "description": "Paths to check; omitted, the whole workspace.",
            "items": {
              "type": "string"
            },
            "type": "array"
          }
        },
        "type": "object"
      },
      "SandboxResume": {
        "additionalProperties": false,
        "description": "`POST /v1/sandboxes/{id}/resume`.",
        "properties": {
          "optimize_for": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/OptimizeFor"
              },
              {
                "type": "null"
              }
            ],
            "description": "Omitted: the sandbox's own setting."
          },
          "spend_cap": {
            "description": "For a sandbox paused at its run's spend cap (`pause_reason: spend_cap`): the run's new\ncap in US dollars, above the one it reached. The sandbox goes on with what the new cap\nleaves, up to its own timeout.",
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          }
        },
        "type": "object"
      },
      "SandboxResumed": {
        "description": "`POST /v1/sandboxes/{id}/resume`.",
        "properties": {
          "note": {
            "description": "What `restarted` means for this sandbox, in one sentence. Absent for a normal resume.",
            "type": [
              "string",
              "null"
            ]
          },
          "ok": {
            "type": "boolean"
          },
          "paused_id": {
            "description": "The pause that was restored: the `paused_id` its pause answered with.",
            "type": "string"
          },
          "recorded": {
            "description": "False if the sandbox came back but the change could not be written down.",
            "type": "boolean"
          },
          "restarted": {
            "description": "True when the sandbox came back from its saved files only: its files are as they were when\nit paused, but the programs that were running then were not kept and start fresh. Absent\n(false) for a normal resume, where everything comes back as it was.",
            "type": "boolean"
          },
          "sandbox_id": {
            "type": "string"
          },
          "state": {
            "description": "`\"ready\"`.",
            "type": "string"
          },
          "took_ms": {
            "description": "Milliseconds the resume took, from the request to the answer.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "ok",
          "sandbox_id",
          "state",
          "paused_id",
          "took_ms",
          "recorded"
        ],
        "type": "object"
      },
      "SandboxSnapshot": {
        "description": "`POST /v1/sandboxes/:id/snapshot` — the reply from photographing a running sandbox.\n\nThe field that matters most is `still_running`. It is the entire difference between\nthis route and `pause`, and it is sent explicitly rather than implied by the absence of an\nerror, because a customer automating \"branch this session and carry on\" needs to be able to\nassert on it.",
        "properties": {
          "alias": {
            "type": [
              "string",
              "null"
            ]
          },
          "background_execs_killed": {
            "description": "Background processes ended to take the snapshot. Reported rather than silent: a live\nsnapshot must not quietly cost a customer their dev server.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "bytes": {
            "$ref": "#/components/schemas/SnapshotBytes",
            "description": "What the image occupies on disk."
          },
          "ok": {
            "type": "boolean"
          },
          "sandbox_id": {
            "description": "The sandbox that was photographed. Still yours, still running.",
            "type": "string"
          },
          "snapshot_id": {
            "description": "An ordinary snapshot id, forkable by every path that forks anything else. There is\ndeliberately no second kind of snapshot: a parallel identifier with its own rules is how\ntwo code paths drift apart.",
            "type": "string"
          },
          "still_running": {
            "description": "Always `true` on a 200. See the type's note.",
            "type": "boolean"
          },
          "tier": {
            "type": "string"
          },
          "took_ms": {
            "description": "Milliseconds the snapshot took, from the request to the answer.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "warnings": {
            "description": "Things the caller should know about what was taken, one `code: sentence` per line. Absent\nwhen there are none. Today the only one is `secrets_in_saved_state`: the sandbox had been\ngiven the value of a secret and the snapshot was taken with `force`, so the snapshot, and\nevery sandbox started from it, can contain that value.",
            "items": {
              "type": "string"
            },
            "type": "array"
          }
        },
        "required": [
          "ok",
          "snapshot_id",
          "sandbox_id",
          "tier",
          "bytes",
          "took_ms",
          "background_execs_killed",
          "still_running"
        ],
        "type": "object"
      },
      "SandboxSnapshotCreate": {
        "additionalProperties": false,
        "description": "`POST /v1/sandboxes/{id}/snapshot`.",
        "properties": {
          "alias": {
            "description": "A name for the new snapshot, unique in the project.",
            "type": [
              "string",
              "null"
            ]
          },
          "force": {
            "description": "Take it even though the sandbox was given a secret's value.",
            "type": "boolean"
          },
          "move_alias": {
            "description": "If another snapshot has `alias`, move the name to the new one (the other stays, unnamed).\nWithout it such an alias is refused.",
            "type": "boolean"
          }
        },
        "type": "object"
      },
      "SandboxState": {
        "oneOf": [
          {
            "enum": [
              "queued",
              "ready",
              "running",
              "ended"
            ],
            "type": "string"
          },
          {
            "const": "paused",
            "description": "Parked: it keeps its state, is not billed and does not count against your concurrency\nlimit until it is resumed (an idle rule or a command wakes it). It was reported as `queued`.",
            "type": "string"
          }
        ],
        "x-promigence-open-enum": true
      },
      "SandboxUsage": {
        "description": "Sandbox time at one tier.",
        "properties": {
          "amount": {
            "description": "USD.",
            "format": "double",
            "type": "number"
          },
          "gib_seconds": {
            "format": "int64",
            "type": "integer"
          },
          "seconds": {
            "format": "int64",
            "type": "integer"
          },
          "vcpu_seconds": {
            "format": "int64",
            "type": "integer"
          }
        },
        "required": [
          "seconds",
          "vcpu_seconds",
          "gib_seconds",
          "amount"
        ],
        "type": "object"
      },
      "SandboxView": {
        "description": "One sandbox, as `GET /v1/sandboxes/{id}` and the rows of `GET /v1/sandboxes` report it.",
        "properties": {
          "attempt": {
            "description": "1 for the first try, 2 for the first retry, and so on.",
            "format": "uint8",
            "maximum": 255,
            "minimum": 0,
            "type": "integer"
          },
          "auto_pause_mode": {
            "description": "What idle means for the rule: `requests` | `activity`.",
            "type": "string"
          },
          "auto_pause_s": {
            "description": "The idle rule it is under: park after this many idle seconds, 0 for never.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "billable_seconds": {
            "description": "Once it has ended, the seconds it is billed for (the run report's `billable_seconds`).\nPresent on `GET /v1/sandboxes/{id}` for an ended sandbox; absent from list rows.",
            "format": "uint64",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "cost_usd": {
            "description": "What it has cost in USD at its run's rates: once it has ended, the run report's `cost`; while\nit is live, the seconds billed so far (running time only). Present on `GET /v1/sandboxes/{id}`\nonce it has started; absent from list rows.",
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "created_at": {
            "description": "When the sandbox was created, RFC 3339: when its run was started, or when the retry or\nreplay that made it was asked for.",
            "type": "string"
          },
          "e2e_ms": {
            "description": "Milliseconds from the start request, after any time queued, to the sandbox being handed\nover: it does not include `queued_ms`. Add `queued_ms` for the whole wait.",
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "egress": {
            "$ref": "#/components/schemas/EgressCounters",
            "description": "Data out, and whether it was cut for the organisation's monthly cap."
          },
          "elapsed_ms": {
            "default": null,
            "description": "Milliseconds of running time since hand-over, time spent paused excluded: what\n`timeout_ms` is measured against, so `timeout_ms - elapsed_ms` is the time it has left.\n`null` before hand-over and once it has ended.",
            "format": "uint64",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "env_verified": {
            "description": "Whether this sandbox's environment passed its checks.",
            "type": "boolean"
          },
          "eta_s": {
            "description": "Seconds until this sandbox is expected to start, with\n`queued_reason: capacity_arriving`. `null` with the other reasons, and once the sandbox has\nwaited longer than the estimate it was first given; `queued_message` then says it is\ntaking longer than expected rather than repeating a number.",
            "format": "uint64",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "execs": {
            "description": "The commands run in this sandbox. Present on `GET /v1/sandboxes/{id}`; absent from the\nrows of a list, which would otherwise carry every byte of every command's output.",
            "items": {
              "$ref": "#/components/schemas/ExecView"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "failure": {
            "description": "What went wrong, rendered against this sandbox's own evidence. `null` on success."
          },
          "labels": {
            "additionalProperties": {
              "type": "string"
            },
            "description": "Inherited from the run. A caller that looked a sandbox up by label needs to see the labels\nit got back, and one that did not needs a way to learn what a sandbox is tagged with.",
            "type": "object"
          },
          "one_time": {
            "description": "True when this is a one-time wait: once the waiting sandboxes can start, the rest of the\nrun starts at once too. False otherwise.",
            "type": [
              "boolean",
              "null"
            ]
          },
          "optimize_for": {
            "$ref": "#/components/schemas/OptimizeFor",
            "description": "What the sandbox asked for."
          },
          "optimize_for_applied": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/OptimizeFor"
              },
              {
                "type": "null"
              }
            ],
            "description": "What its latest start or resume actually got; `null` before the first."
          },
          "outcome": {
            "description": "Why it ended; `null` while it is still alive.",
            "type": [
              "string",
              "null"
            ]
          },
          "pause_expires_at": {
            "description": "While it is paused: when it will be deleted, with its files and state, unless it is\nresumed before then (RFC 3339). A paused sandbox is kept for 30 days, and resuming it\nstarts the 30 days again. Absent while it is not paused, and for a paused sandbox that is\nnot due to be deleted.",
            "type": [
              "string",
              "null"
            ]
          },
          "pause_reason": {
            "description": "Why it is paused, when a limit paused it rather than a request: `spend_cap` (its run\nreached its spend cap) or `credits_exhausted` (the organization's credits ran out). Its\nfiles and state are kept and paused time is not billed; it resumes once the cap is raised\nor credits are added. Absent otherwise.",
            "type": [
              "string",
              "null"
            ]
          },
          "queued_message": {
            "description": "The same, in words, ready to show a person.",
            "type": [
              "string",
              "null"
            ]
          },
          "queued_ms": {
            "description": "Milliseconds spent waiting for capacity.",
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "queued_reason": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/QueuedReason"
              },
              {
                "type": "null"
              }
            ]
          },
          "ready_ms": {
            "description": "Milliseconds until the sandbox was ready to take work.",
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "replay_of": {
            "description": "The sandbox this one is a replay of.",
            "type": [
              "string",
              "null"
            ]
          },
          "retried_by": {
            "description": "The retry that replaced this sandbox, if it was retried.",
            "type": [
              "string",
              "null"
            ]
          },
          "retry_of": {
            "description": "The sandbox this one is a retry of.",
            "type": [
              "string",
              "null"
            ]
          },
          "run_id": {
            "description": "The run this sandbox belongs to.",
            "type": "string"
          },
          "sandbox_id": {
            "type": "string"
          },
          "snapshot_id": {
            "description": "The snapshot it was started from, as its run names it (`GET /v1/runs/{id}`): the\nsnapshot's id, or `promigence/base` for the built-in base.",
            "type": "string"
          },
          "state": {
            "description": "`queued` | `ready` | `running` | `paused` | `ended`.",
            "type": "string"
          },
          "t_end": {
            "description": "When it ended, RFC 3339.",
            "type": [
              "string",
              "null"
            ]
          },
          "t_handoff": {
            "description": "When the sandbox was handed over, RFC 3339.",
            "type": [
              "string",
              "null"
            ]
          },
          "timeout_ms": {
            "default": null,
            "description": "The lifetime this sandbox is bound to, in milliseconds of running time: time spent paused\ndoes not count. A `PATCH` with a larger `timeout_ms` extends it.",
            "format": "uint64",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "verify_each_ms": {
            "description": "Milliseconds the per-sandbox verification took, when `verify_each` was asked for.",
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "warnings": {
            "items": {
              "type": "string"
            },
            "type": "array"
          }
        },
        "required": [
          "sandbox_id",
          "run_id",
          "snapshot_id",
          "created_at",
          "labels",
          "state",
          "attempt",
          "env_verified",
          "auto_pause_s",
          "auto_pause_mode",
          "egress",
          "optimize_for",
          "warnings"
        ],
        "type": "object"
      },
      "ScoreMode": {
        "description": "How the grader's result is read.",
        "oneOf": [
          {
            "const": "exit",
            "description": "Exit 0 = pass. No score.",
            "type": "string"
          },
          {
            "const": "last_line_json",
            "description": "The last non-empty line is `{\"score\": 0.8, \"pass\": true}`. `pass` decides when present,\notherwise the exit code does; the score is reported either way.",
            "type": "string"
          },
          {
            "const": "tap",
            "description": "TAP: a `1..N` plan and `ok` / `not ok` lines. Pass = a plan, no `not ok`, N results.",
            "type": "string"
          }
        ],
        "x-promigence-open-enum": true
      },
      "Sealed": {
        "description": "The three sections a customer gets as a digest instead of as content.",
        "properties": {
          "layers": {
            "description": "`blake3:<hex>` of the contents section.",
            "type": "string"
          },
          "machine": {
            "description": "`blake3:<hex>` of the machine section.",
            "type": "string"
          },
          "platform": {
            "description": "`blake3:<hex>` of the platform section.",
            "type": "string"
          }
        },
        "required": [
          "platform",
          "machine",
          "layers"
        ],
        "type": "object"
      },
      "SealedManifest": {
        "description": "The manifest as the API returns it: the sections that describe *how* the environment runs\nare replaced by their digests under `sealed`; identity, provenance and verification are\nunchanged.\n\nA sealed manifest still names exactly one environment: `manifest_hash` is the full hash of the\ncontent keys, and `sealed.*` are the section digests a full bundle would carry, so a\n`.promigence` built from it can be cited, committed and handed back to the API.",
        "properties": {
          "alias": {
            "type": [
              "string",
              "null"
            ]
          },
          "id": {
            "type": [
              "string",
              "null"
            ]
          },
          "manifest_hash": {
            "description": "`blake3:<hex>` of the canonical JSON of the manifest's content keys — the full form of the\nmanifest's `id`, so two sealed manifests are equal exactly when their environments are.",
            "type": "string"
          },
          "provenance": {
            "$ref": "#/components/schemas/Provenance"
          },
          "schema": {
            "type": "string"
          },
          "sealed": {
            "$ref": "#/components/schemas/Sealed"
          },
          "verification": {
            "$ref": "#/components/schemas/Verification"
          },
          "visibility": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Visibility"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "schema",
          "manifest_hash",
          "provenance",
          "verification",
          "sealed"
        ],
        "type": "object"
      },
      "SealedManifestView": {
        "description": "`GET /v1/snapshots/{id}/manifest` — the sealed manifest: what the environment is built from\nand how it was verified, with the unpublished sections given as digests.",
        "properties": {
          "cached_at": {
            "description": "When this copy of the manifest was taken, RFC 3339.",
            "type": "string"
          },
          "manifest": {
            "$ref": "#/components/schemas/SealedManifest"
          },
          "snapshot_id": {
            "type": "string"
          }
        },
        "required": [
          "snapshot_id",
          "cached_at",
          "manifest"
        ],
        "type": "object"
      },
      "SearchMatch": {
        "description": "One hit from a search. A name-only search fills `path` and leaves the rest null; a content\nsearch names the line it found and the line itself.",
        "properties": {
          "line": {
            "default": null,
            "description": "1-based.",
            "format": "uint32",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "path": {
            "type": "string"
          },
          "text": {
            "default": null,
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "path"
        ],
        "type": "object"
      },
      "SearchResult": {
        "description": "The reply to `GET /v1/sandboxes/:id/files/search`.",
        "properties": {
          "matches": {
            "items": {
              "$ref": "#/components/schemas/SearchMatch"
            },
            "type": "array"
          },
          "note": {
            "description": "The cut in words, and how to search the rest. Absent when nothing was cut.",
            "type": [
              "string",
              "null"
            ]
          },
          "path": {
            "type": "string"
          },
          "sandbox_id": {
            "type": "string"
          },
          "served_by": {
            "type": [
              "string",
              "null"
            ]
          },
          "truncated": {
            "type": "boolean"
          },
          "truncated_by": {
            "description": "Why `truncated` is true: `entries` — a search looks at the first 10,000 entries under\n`path` (by name, a directory's own entries before its subdirectories') and stopped there,\nso files past them were not searched; `matches` — it found `limit` matches and stopped.\nAbsent when nothing was cut.",
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "sandbox_id",
          "path",
          "matches",
          "truncated"
        ],
        "type": "object"
      },
      "SecretDeleted": {
        "description": "`DELETE /v1/secrets/{name}`.",
        "properties": {
          "deleted": {
            "type": "boolean"
          },
          "name": {
            "type": "string"
          }
        },
        "required": [
          "name",
          "deleted"
        ],
        "type": "object"
      },
      "SecretList": {
        "description": "`GET /v1/secrets` — names and shapes, never values.",
        "properties": {
          "secrets": {
            "items": {
              "$ref": "#/components/schemas/SecretSummary"
            },
            "type": "array"
          }
        },
        "required": [
          "secrets"
        ],
        "type": "object"
      },
      "SecretRaw": {
        "description": "Whether a host-bound secret may be delivered as the value itself.",
        "enum": [
          "allowed",
          "refused"
        ],
        "type": "string",
        "x-promigence-open-enum": true
      },
      "SecretSet": {
        "additionalProperties": false,
        "description": "`POST /v1/secrets`: store a value. Setting a name again replaces its value; a field left out\nkeeps what was stored.",
        "properties": {
          "body": {
            "description": "Let the secret be used in request bodies to its hosts. Not available yet: `true` is refused,\n`false` (the default) is accepted.",
            "type": [
              "boolean",
              "null"
            ]
          },
          "headers": {
            "description": "Request headers the value may be sent in.",
            "items": {
              "type": "string"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "hosts": {
            "description": "Host names the value may be sent to (never addresses).",
            "items": {
              "type": "string"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "name": {
            "description": "A valid environment variable name.",
            "type": "string"
          },
          "query": {
            "description": "Let the secret be used in query strings to its hosts. Not available yet: `true` is refused,\n`false` (the default) is accepted.",
            "type": [
              "boolean",
              "null"
            ]
          },
          "raw": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/SecretRaw"
              },
              {
                "type": "null"
              }
            ],
            "description": "Whether a command may ask for the value itself."
          },
          "scan_responses": {
            "description": "Mask the value in responses from its hosts.",
            "type": [
              "boolean",
              "null"
            ]
          },
          "value": {
            "type": "string"
          }
        },
        "required": [
          "name",
          "value"
        ],
        "type": "object"
      },
      "SecretStored": {
        "description": "`POST /v1/secrets`. The value is write-only: no route ever returns it, including this one.",
        "properties": {
          "bytes": {
            "description": "The length of the value that was stored, in bytes.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "created": {
            "description": "False when an existing secret of that name was overwritten in place.",
            "type": "boolean"
          },
          "env": {
            "additionalProperties": {
              "type": "string"
            },
            "description": "The variables a sandbox that names this secret is also given, each set to the address in\n`urls` for a provider whose SDKs read their base URL from a variable (with the path those\nSDKs expect), such as `OPENAI_BASE_URL` for `api.openai.com` and `ANTHROPIC_BASE_URL` for\n`api.anthropic.com`. A variable the caller sets itself wins. Absent when there is none.",
            "type": "object"
          },
          "hosts": {
            "description": "The hosts the secret is bound to. Absent when it is not bound, and a sandbox that names\nit is given the value itself.",
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "name": {
            "type": "string"
          },
          "next": {
            "description": "What to do next, ready to run.",
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "placeholder": {
            "description": "What the variable holds, in place of the value, in a sandbox that names this secret.\nPresent when `hosts` is.",
            "type": [
              "string",
              "null"
            ]
          },
          "raw": {
            "description": "`refused` when the value itself can never be given to a sandbox, `allowed` (the default)\notherwise. Present when `hosts` is.",
            "type": [
              "string",
              "null"
            ]
          },
          "scan_responses": {
            "description": "Whether the value is masked out of responses from the bound hosts. Present when `hosts`\nis.",
            "type": [
              "boolean",
              "null"
            ]
          },
          "updated_at": {
            "description": "RFC 3339.",
            "type": "string"
          },
          "urls": {
            "description": "For each of `hosts`, in the same order, the address a sandbox sends that host's requests\nto, with the request's path added after it. Requests sent there are authenticated with the\nsecret; a request sent straight to the host is not. For a `*.` host, put the name in place\nof the `*`. Present when `hosts` is.",
            "items": {
              "type": "string"
            },
            "type": "array"
          }
        },
        "required": [
          "name",
          "created",
          "bytes",
          "updated_at",
          "next"
        ],
        "type": "object"
      },
      "SecretSummary": {
        "description": "One stored secret, without its value.",
        "properties": {
          "bytes": {
            "description": "The length of the stored value, in bytes.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "created_at": {
            "description": "RFC 3339.",
            "type": "string"
          },
          "env": {
            "additionalProperties": {
              "type": "string"
            },
            "description": "The base-URL variables a sandbox that names this secret is also given, as\n`POST /v1/secrets` answers them. Absent when there is none.",
            "type": "object"
          },
          "headers": {
            "description": "The request headers the secret is used in. Present when `hosts` is.",
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "hosts": {
            "description": "The hosts the secret is bound to. Absent when it is not bound: a sandbox that names it is\nthen given the value itself. When present, requests to these hosts sent through `urls`\nare authenticated with it, and the value stays out of the sandbox unless a run asks for\nit and `raw` allows it.",
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "name": {
            "type": "string"
          },
          "raw": {
            "description": "`refused` when the value itself can never be given to a sandbox, `allowed` (the default)\notherwise. Present when `hosts` is.",
            "type": [
              "string",
              "null"
            ]
          },
          "scan_responses": {
            "description": "Whether the value is masked out of responses from the bound hosts. Present when `hosts`\nis.",
            "type": [
              "boolean",
              "null"
            ]
          },
          "updated_at": {
            "description": "RFC 3339.",
            "type": "string"
          },
          "urls": {
            "description": "For each of `hosts`, in the same order, the address a sandbox sends its requests to, as\n`POST /v1/secrets` answers it. Present when `hosts` is.",
            "items": {
              "type": "string"
            },
            "type": "array"
          }
        },
        "required": [
          "name",
          "bytes",
          "created_at",
          "updated_at"
        ],
        "type": "object"
      },
      "SecretUse": {
        "anyOf": [
          {
            "description": "The stored secret's name; the variable has the same name.",
            "type": "string"
          },
          {
            "$ref": "#/components/schemas/SecretUseBound",
            "description": "A stored secret under another variable name."
          }
        ],
        "description": "A stored secret a command receives: its name (delivered under the same name), or an object\nnaming the variable it is delivered as."
      },
      "SecretUseBound": {
        "additionalProperties": false,
        "description": "A stored secret delivered under a variable name of your choosing.",
        "properties": {
          "as": {
            "description": "The environment variable it is delivered as. Defaults to `name`.",
            "type": [
              "string",
              "null"
            ]
          },
          "mode": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/SecretUseMode"
              },
              {
                "type": "null"
              }
            ],
            "description": "`raw` gives the command the value itself of a secret bound to hosts (refused when the\nsecret's `raw` is `refused`); omitted, the value stays out of the sandbox and requests to\nits hosts sent through its `urls` are authenticated with it."
          },
          "name": {
            "description": "The stored secret's name.",
            "type": "string"
          }
        },
        "required": [
          "name"
        ],
        "type": "object"
      },
      "SecretUseMode": {
        "description": "How a host-bound secret is delivered to a command.",
        "enum": [
          "raw",
          "placeholder"
        ],
        "type": "string",
        "x-promigence-open-enum": true
      },
      "ServiceStatus": {
        "description": "One service, as the status page shows it.",
        "properties": {
          "last_health_at": {
            "description": "RFC 3339: the last time it was seen working; `null` when it never has been.",
            "type": [
              "string",
              "null"
            ]
          },
          "name": {
            "description": "`api` | `sandboxes`.",
            "type": "string"
          },
          "state": {
            "description": "`up` | `degraded` | `down`.",
            "type": "string"
          }
        },
        "required": [
          "name",
          "state"
        ],
        "type": "object"
      },
      "Session": {
        "description": "`POST /v1/auth/session` — an identity token exchanged for an account. `201` when the first\ncall for an identity created the user, the organisation and the trial; `200` afterwards.",
        "properties": {
          "api_key": {
            "description": "**The secret of the key that was minted, sent once.** Only when `mint_key` was asked for.",
            "type": [
              "string",
              "null"
            ]
          },
          "created": {
            "description": "True when this call created the account.",
            "type": "boolean"
          },
          "key": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/KeyView"
              },
              {
                "type": "null"
              }
            ],
            "description": "The key that was minted, without its secret. Only when `mint_key` was asked for."
          },
          "org": {
            "$ref": "#/components/schemas/SessionOrg"
          },
          "referral": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ReferralApplied"
              },
              {
                "type": "null"
              }
            ],
            "description": "Only when a first sign-in sent a referral code (`promigence login --ref`): what became of\nit. A code that does not apply never stops the sign-in."
          },
          "trial": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/SessionTrial"
              },
              {
                "type": "null"
              }
            ],
            "description": "Only when the account was created: what the trial granted."
          },
          "user": {
            "$ref": "#/components/schemas/UserView"
          }
        },
        "required": [
          "user",
          "org",
          "created"
        ],
        "type": "object"
      },
      "SessionCreate": {
        "additionalProperties": false,
        "description": "`POST /v1/auth/session`: exchange a sign-in token.",
        "properties": {
          "key_name": {
            "description": "The minted key's name (default `cli`, at most 64 characters).",
            "type": [
              "string",
              "null"
            ]
          },
          "mint_key": {
            "description": "Also mint an API key.",
            "type": "boolean"
          },
          "nonce": {
            "description": "The login nonce, when the sign-in was started with one.",
            "type": [
              "string",
              "null"
            ]
          },
          "ref": {
            "description": "A referral code.",
            "type": [
              "string",
              "null"
            ]
          }
        },
        "type": "object"
      },
      "SessionOrg": {
        "description": "The organisation a sign-in lands in.",
        "properties": {
          "default_spend_cap": {
            "description": "USD.",
            "format": "double",
            "type": "number"
          },
          "max_inflight": {
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "org_id": {
            "type": "string"
          },
          "role": {
            "description": "The user's role in it.",
            "type": "string"
          }
        },
        "required": [
          "org_id",
          "name",
          "role",
          "max_inflight",
          "default_spend_cap"
        ],
        "type": "object"
      },
      "SessionTrial": {
        "description": "What a new account's trial granted.",
        "properties": {
          "credits_granted": {
            "description": "USD.",
            "format": "double",
            "type": "number"
          },
          "second_trial": {
            "description": "True when no credit was granted because this identity had a trial before.",
            "type": "boolean"
          }
        },
        "required": [
          "credits_granted",
          "second_trial"
        ],
        "type": "object"
      },
      "SnapshotAliasSet": {
        "additionalProperties": false,
        "description": "`PUT /v1/snapshots/{id}/alias`. `alias` is required: the new name, or `null` to remove it.",
        "properties": {
          "alias": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "alias"
        ],
        "type": "object"
      },
      "SnapshotBytes": {
        "description": "What an image occupies in storage: `allocated`, which can be less than its size.",
        "properties": {
          "allocated": {
            "description": "Bytes on disk.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "allocated"
        ],
        "type": "object"
      },
      "SnapshotCreate": {
        "additionalProperties": false,
        "description": "`POST /v1/snapshots`. One source form is required: `repo` with `commit`, `image`, or\n`dockerfile`.",
        "properties": {
          "alias": {
            "description": "A name for it, unique in the project.",
            "type": [
              "string",
              "null"
            ]
          },
          "commit": {
            "description": "The full 40-character commit sha to build (the repository form).",
            "type": [
              "string",
              "null"
            ]
          },
          "dockerfile": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/DockerfileSource"
              },
              {
                "type": "null"
              }
            ],
            "description": "Build from a Dockerfile."
          },
          "env": {
            "additionalProperties": {
              "type": "string"
            },
            "description": "Image and Dockerfile forms: environment variables for every command, terminal and SSH\nsession in sandboxes from this snapshot (and for its own `setup`, `verify` and `start`),\nset over the image's own `ENV` as `docker run -e` sets them. A value may build on a\nvariable the image sets with `${containerEnv:NAME}`, or `${containerEnv:NAME:default}`\nwhen the image may not set it: `\"PATH\": \"${containerEnv:PATH}:/opt/tools/bin\"`.",
            "type": "object"
          },
          "from": {
            "description": "`github:` repositories: the snapshot the build starts from, by id or alias. Default\n`promigence/base`.",
            "type": [
              "string",
              "null"
            ]
          },
          "grade": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/GradeSpec"
              },
              {
                "type": "null"
              }
            ],
            "description": "The snapshot's default grader for runs that name none."
          },
          "grade_output": {
            "description": "Runs that use this default grader keep what it prints, as `grade_output` on\n`POST /v1/runs` does, unless the run says otherwise. Needs `grade`.",
            "type": "boolean"
          },
          "image": {
            "description": "A container image, `REF@sha256:<digest>`; a tag is resolved to its digest first.",
            "type": [
              "string",
              "null"
            ]
          },
          "ref": {
            "description": "`github:` repositories: a branch, a tag or a commit sha, resolved to the commit it names\nwhen the build is accepted. Default: the repository's default branch.",
            "type": [
              "string",
              "null"
            ]
          },
          "registry_secret": {
            "description": "A stored secret holding the registry credentials for a private `image`.",
            "type": [
              "string",
              "null"
            ]
          },
          "repo": {
            "description": "A public git URL (the repository form), or `github:owner/name`: a repository the\norganization's GitHub connection can read (`GET /v1/integrations/github/repos`).",
            "type": [
              "string",
              "null"
            ]
          },
          "setup": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/OneOrMany"
              },
              {
                "type": "null"
              }
            ],
            "description": "Commands run once, in order, before `verify`."
          },
          "setup_user": {
            "description": "Image and Dockerfile forms: the user its `start`, `setup` and `verify` run as (for example\nthe snapshot's own `user`). Default: `root`.",
            "type": [
              "string",
              "null"
            ]
          },
          "sources": {
            "description": "Extra repositories cloned before `setup` (repository form only, at most 8).",
            "items": {
              "$ref": "#/components/schemas/SourceRequest"
            },
            "type": "array"
          },
          "start": {
            "description": "A command that keeps running in every sandbox (image and Dockerfile forms).",
            "type": [
              "string",
              "null"
            ]
          },
          "tier": {
            "description": "The sandbox size it is built and forked at.",
            "type": [
              "string",
              "null"
            ]
          },
          "track": {
            "description": "`github:` repositories with a branch `ref` and an `alias`: every push to the branch builds\nthe snapshot again and moves the alias to it. Each automatic build is a normal build,\ncharged to the organization.",
            "type": "boolean"
          },
          "user": {
            "description": "Image and Dockerfile forms: the user commands, terminals and SSH sessions in its sandboxes\nrun as when they name none. A user name or uid, with an optional `:group` or `:gid`, as an\nimage's `USER` takes it; `root` for root. Default: the image's own `USER`, as `docker run`\ndoes (root when it sets none).",
            "type": [
              "string",
              "null"
            ]
          },
          "verify": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/VerifyRequest"
              },
              {
                "type": "null"
              }
            ],
            "description": "The command that must exit 0 for the snapshot to be stored. Required in the repository\nform."
          }
        },
        "type": "object"
      },
      "SnapshotCreated": {
        "anyOf": [
          {
            "$ref": "#/components/schemas/BuildQueued"
          },
          {
            "$ref": "#/components/schemas/BuildJoined"
          },
          {
            "$ref": "#/components/schemas/SnapshotDeduped"
          }
        ],
        "description": "`POST /v1/snapshots` — one of three answers, told apart by `state` and by which of\n`deduped` / `joined` is present:\n\n* `202` [`BuildQueued`]: a new build was started; poll `build_id`.\n* `202` [`BuildJoined`]: an identical build was already in progress and this answer is that\n  build (`joined: true`); wait on it as if it were your own.\n* `200` [`SnapshotDeduped`]: these inputs are already built (`deduped: true`); the snapshot\n  is in the answer and nothing was started or charged.\n\nThe `alias` asked for names the snapshot of whichever answer it is."
      },
      "SnapshotDeduped": {
        "description": "Inputs that are already built: the existing snapshot, named with the alias that was asked for.",
        "properties": {
          "alias": {
            "description": "The mutable name. The id and the hash behind it are not mutable.",
            "type": [
              "string",
              "null"
            ]
          },
          "alias_applied": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "alias_requested": {
            "description": "The alias that was asked for, when the snapshot did not hold it. The snapshot takes it\n(`alias_applied: true`) as a new build would: another snapshot of the project that had it\nkeeps its row, without a name. A snapshot has one alias, so a name it had before gives\nway, and `warnings` says which.",
            "type": [
              "string",
              "null"
            ]
          },
          "build_id": {
            "description": "The build that produced it.",
            "type": "string"
          },
          "commit": {
            "type": "string"
          },
          "created_at": {
            "description": "RFC 3339.",
            "type": "string"
          },
          "deduped": {
            "description": "Always true here.",
            "type": "boolean"
          },
          "files_digest": {
            "description": "`blake3:<hex>` of the snapshot's files and the record of what built them. The same for as\nlong as the snapshot exists. Only on\n`GET /v1/snapshots/{id}`; absent when the snapshot records no file digests.",
            "type": [
              "string",
              "null"
            ]
          },
          "history": {
            "description": "What happened to it, one line per event, oldest first: built and verified, and each time it\nwas verified again (files unchanged). Only on\n`GET /v1/snapshots/{id}`.",
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "idempotent_replay": {
            "description": "Present, and true, only when this is the stored answer to an `Idempotency-Key` that was\nseen before.",
            "type": [
              "boolean",
              "null"
            ]
          },
          "idempotent_replay_age_s": {
            "description": "Present when `idempotent_replay` is true: how many seconds ago that first answer was\ngiven, so a client can say which earlier request this repeats.",
            "format": "uint64",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "last_verified_at": {
            "description": "RFC 3339.",
            "type": [
              "string",
              "null"
            ]
          },
          "repo": {
            "type": "string"
          },
          "setup": {
            "description": "The commands run to prepare the workspace.",
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "snapshot_id": {
            "type": "string"
          },
          "source": {
            "description": "What it was built from: a repository and commit, an image and digest, or a Dockerfile\nand the digest of its context. The `kind` field says which."
          },
          "state": {
            "description": "`verified`, or `built` when the snapshot was stored with no verification command to run.",
            "type": "string"
          },
          "template": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/SnapshotTemplateRef"
              },
              {
                "type": "null"
              }
            ],
            "description": "The template this snapshot is, or was made from, and whether a newer version of it is out.\nAbsent when it comes from no template."
          },
          "tier": {
            "type": "string"
          },
          "tier_assigned": {
            "description": "The tier it was built and verified at. Forking it at another shape is refused.",
            "type": "string"
          },
          "unavailable": {
            "description": "Set when this snapshot can no longer be started, and why: it could not be saved. A fork of it is refused `snapshot_unavailable`. Absent\nwhile it can be started.",
            "type": [
              "string",
              "null"
            ]
          },
          "user": {
            "description": "The user commands, terminals and SSH sessions in its sandboxes run as when they name\nnone: its image's own `USER`, or the `user` it was created with. Absent: root.",
            "type": [
              "string",
              "null"
            ]
          },
          "verification": {
            "description": "What the verification command did when it last ran."
          },
          "verified": {
            "description": "True when a verification command was recorded, which is what makes the snapshot\nreproducible rather than merely saved.",
            "type": "boolean"
          },
          "verify": {
            "$ref": "#/components/schemas/VerifyCmd"
          },
          "visibility": {
            "description": "`private` | `public`.",
            "type": "string"
          },
          "warnings": {
            "description": "Things whoever forks this snapshot should know, one `code: sentence` per line. Absent\nwhen there are none.",
            "items": {
              "type": "string"
            },
            "type": "array"
          }
        },
        "required": [
          "snapshot_id",
          "visibility",
          "source",
          "verified",
          "repo",
          "commit",
          "setup",
          "verify",
          "tier",
          "tier_assigned",
          "build_id",
          "verification",
          "created_at",
          "deduped",
          "state"
        ],
        "type": "object"
      },
      "SnapshotDeleted": {
        "description": "`DELETE /v1/snapshots/{id}`.\n\nBoth ids come back because you may have passed an alias and need to know which row that was.",
        "properties": {
          "alias": {
            "type": [
              "string",
              "null"
            ]
          },
          "deleted": {
            "type": "boolean"
          },
          "ok": {
            "type": "boolean"
          },
          "snapshot_id": {
            "type": "string"
          }
        },
        "required": [
          "ok",
          "snapshot_id",
          "deleted"
        ],
        "type": "object"
      },
      "SnapshotList": {
        "description": "`GET /v1/snapshots` — one page, newest first.",
        "properties": {
          "limit": {
            "description": "The page size that was applied.",
            "format": "int64",
            "type": "integer"
          },
          "next_cursor": {
            "description": "Pass back as `?cursor=` for the next page; `null` on the last page.",
            "type": [
              "string",
              "null"
            ]
          },
          "snapshots": {
            "items": {
              "$ref": "#/components/schemas/SnapshotView"
            },
            "type": "array"
          }
        },
        "required": [
          "snapshots",
          "limit"
        ],
        "type": "object"
      },
      "SnapshotTemplateRef": {
        "description": "What a snapshot was made from, when it was made from a template (`template` on a snapshot):\nthe version it came from and whether a newer one is out.",
        "properties": {
          "latest_version": {
            "format": "int64",
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "update": {
            "description": "`current`, `available` (a newer version is out) or `security` (a newer version fixes a\nsecurity problem: rebuild from it soon).",
            "type": "string"
          },
          "version": {
            "format": "int64",
            "type": "integer"
          }
        },
        "required": [
          "name",
          "title",
          "version",
          "latest_version",
          "update"
        ],
        "type": "object"
      },
      "SnapshotVerify": {
        "additionalProperties": false,
        "description": "`POST /v1/snapshots/{id}/verify`.",
        "properties": {
          "spend_cap": {
            "description": "The most it may cost, in USD.",
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "timeout_ms": {
            "description": "Milliseconds the verification may run. Default 15 minutes.",
            "format": "uint64",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          }
        },
        "type": "object"
      },
      "SnapshotVerifyStarted": {
        "description": "`POST /v1/snapshots/{id}/verify` — the snapshot's own verification command, re-run in a\nfresh fork. It is a real run: the whole `POST /v1/runs` answer, plus what was verified and\nwhat it costs.",
        "properties": {
          "alias": {
            "type": [
              "string",
              "null"
            ]
          },
          "count": {
            "description": "How many sandboxes were asked for.",
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "idempotent_replay": {
            "description": "True when this is the stored answer to an `Idempotency-Key` that was seen before, and no\nsecond run was started.",
            "type": "boolean"
          },
          "idempotent_replay_age_s": {
            "description": "Present when `idempotent_replay` is true: how many seconds ago that first answer was\ngiven, so a client can say which earlier request this repeats.",
            "format": "uint64",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "last_verified_at": {
            "description": "When the snapshot was last verified before this run, RFC 3339.",
            "type": [
              "string",
              "null"
            ]
          },
          "launched": {
            "description": "How many were started. Fewer than `count` only with `allow_partial`, and the reason is in\n`warnings`.",
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "per_second_usd": {
            "format": "double",
            "type": "number"
          },
          "preemptible": {
            "description": "True when the run was posted at the preemptible rate: its sandboxes can be stopped early,\nand one stopped that way bills nothing.",
            "type": "boolean"
          },
          "price": {
            "description": "What one full run of it may cost, in USD.",
            "format": "double",
            "type": "number"
          },
          "quote": {
            "$ref": "#/components/schemas/Quote"
          },
          "run_id": {
            "type": "string"
          },
          "sandboxes": {
            "items": {
              "$ref": "#/components/schemas/RunSandboxRef"
            },
            "type": "array"
          },
          "seconds": {
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "snapshot": {
            "description": "The snapshot, resolved.",
            "type": "string"
          },
          "snapshot_arg": {
            "description": "The snapshot as you named it — an id, an alias, or a path.",
            "type": "string"
          },
          "snapshot_id": {
            "description": "The snapshot's id, as `GET /v1/runs/{id}` and the report give it: `\"\"` for the built-in\nbase. Never `null` from this API; typed nullable for older answers.",
            "type": [
              "string",
              "null"
            ]
          },
          "spend_cap": {
            "description": "The most this run may cost, in USD.",
            "format": "double",
            "type": "number"
          },
          "state": {
            "description": "`\"running\"`.",
            "type": "string"
          },
          "tier": {
            "type": "string"
          },
          "timeout_ms": {
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "verify": {
            "description": "The verification command, as it was recorded.",
            "type": "string"
          },
          "warnings": {
            "description": "What was **not** started and why, said when it is decided rather than discovered in the\nreport.",
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "workspace": {
            "description": "The directory it runs in.",
            "type": "string"
          }
        },
        "required": [
          "run_id",
          "state",
          "snapshot",
          "snapshot_arg",
          "count",
          "launched",
          "timeout_ms",
          "tier",
          "preemptible",
          "spend_cap",
          "quote",
          "sandboxes",
          "warnings",
          "idempotent_replay",
          "verify",
          "workspace",
          "price",
          "seconds",
          "per_second_usd"
        ],
        "type": "object"
      },
      "SnapshotView": {
        "description": "One snapshot: what it was built from, whether it was verified, and what it runs on.",
        "properties": {
          "alias": {
            "description": "The mutable name. The id and the hash behind it are not mutable.",
            "type": [
              "string",
              "null"
            ]
          },
          "build_id": {
            "description": "The build that produced it.",
            "type": "string"
          },
          "commit": {
            "type": "string"
          },
          "created_at": {
            "description": "RFC 3339.",
            "type": "string"
          },
          "files_digest": {
            "description": "`blake3:<hex>` of the snapshot's files and the record of what built them. The same for as\nlong as the snapshot exists. Only on\n`GET /v1/snapshots/{id}`; absent when the snapshot records no file digests.",
            "type": [
              "string",
              "null"
            ]
          },
          "history": {
            "description": "What happened to it, one line per event, oldest first: built and verified, and each time it\nwas verified again (files unchanged). Only on\n`GET /v1/snapshots/{id}`.",
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "last_verified_at": {
            "description": "RFC 3339.",
            "type": [
              "string",
              "null"
            ]
          },
          "repo": {
            "type": "string"
          },
          "setup": {
            "description": "The commands run to prepare the workspace.",
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "snapshot_id": {
            "type": "string"
          },
          "source": {
            "description": "What it was built from: a repository and commit, an image and digest, or a Dockerfile\nand the digest of its context. The `kind` field says which."
          },
          "template": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/SnapshotTemplateRef"
              },
              {
                "type": "null"
              }
            ],
            "description": "The template this snapshot is, or was made from, and whether a newer version of it is out.\nAbsent when it comes from no template."
          },
          "tier": {
            "type": "string"
          },
          "tier_assigned": {
            "description": "The tier it was built and verified at. Forking it at another shape is refused.",
            "type": "string"
          },
          "unavailable": {
            "description": "Set when this snapshot can no longer be started, and why: it could not be saved. A fork of it is refused `snapshot_unavailable`. Absent\nwhile it can be started.",
            "type": [
              "string",
              "null"
            ]
          },
          "user": {
            "description": "The user commands, terminals and SSH sessions in its sandboxes run as when they name\nnone: its image's own `USER`, or the `user` it was created with. Absent: root.",
            "type": [
              "string",
              "null"
            ]
          },
          "verification": {
            "description": "What the verification command did when it last ran."
          },
          "verified": {
            "description": "True when a verification command was recorded, which is what makes the snapshot\nreproducible rather than merely saved.",
            "type": "boolean"
          },
          "verify": {
            "$ref": "#/components/schemas/VerifyCmd"
          },
          "visibility": {
            "description": "`private` | `public`.",
            "type": "string"
          },
          "warnings": {
            "description": "Things whoever forks this snapshot should know, one `code: sentence` per line. Absent\nwhen there are none.",
            "items": {
              "type": "string"
            },
            "type": "array"
          }
        },
        "required": [
          "snapshot_id",
          "visibility",
          "source",
          "verified",
          "repo",
          "commit",
          "setup",
          "verify",
          "tier",
          "tier_assigned",
          "build_id",
          "verification",
          "created_at"
        ],
        "type": "object"
      },
      "Source": {
        "description": "One additional repository a world is built from: a URL, a full commit, and the path inside\nthe machine it is cloned to.\n\nThe three fields are the whole of it on purpose. A branch is not a pin and a shallow fetch of\na sha needs nothing else, so there is no `ref`, no `depth` and no `submodules` — every one of\nthose would be a knob whose value is not recorded anywhere and therefore a way to make two\nbuilds of one config differ again.",
        "properties": {
          "commit": {
            "description": "40 lowercase hex.",
            "type": "string"
          },
          "path": {
            "description": "Absolute, inside the workspace's parent (`/work`), normalised. Stored absolute so the manifest says where the tree landed\nrather than where somebody's relative path would have landed.",
            "type": "string"
          },
          "repo": {
            "description": "The git remote. Same grammar as the primary `repo`: a remote, never a local path.",
            "type": "string"
          }
        },
        "required": [
          "repo",
          "commit",
          "path"
        ],
        "type": "object"
      },
      "SourceRequest": {
        "additionalProperties": false,
        "description": "One extra repository.",
        "properties": {
          "commit": {
            "description": "The full 40-character commit sha.",
            "type": "string"
          },
          "path": {
            "description": "Where it is cloned; defaults to the repository's name beside the workspace.",
            "type": [
              "string",
              "null"
            ]
          },
          "repo": {
            "type": "string"
          }
        },
        "required": [
          "repo",
          "commit"
        ],
        "type": "object"
      },
      "SpendDetail": {
        "description": "Spend, split so an invoice can be reconciled without exporting anything.",
        "properties": {
          "billable_seconds": {
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "by_kind": {
            "additionalProperties": {
              "format": "double",
              "type": "number"
            },
            "description": "USD by kind of charge (`sandbox`, `build`, `egress`, …).",
            "type": "object"
          },
          "currency": {
            "description": "`usd`.",
            "type": "string"
          },
          "total": {
            "description": "USD.",
            "format": "double",
            "type": "number"
          }
        },
        "required": [
          "total",
          "currency",
          "billable_seconds",
          "by_kind"
        ],
        "type": "object"
      },
      "SshAccess": {
        "description": "What `POST /v1/sandboxes/:id/ssh` answers.",
        "properties": {
          "expires_at": {
            "description": "When the key and the token both stop working (RFC 3339).",
            "type": "string"
          },
          "fingerprint": {
            "description": "`SHA256:…` of the public key that was authorised, as `ssh-keygen -lf` prints it.",
            "type": "string"
          },
          "host": {
            "description": "The host to give `ssh`. It is an alias resolved by the tunnel, not a routable name.",
            "type": "string"
          },
          "host_key": {
            "description": "The sandbox's own host key, as a `known_hosts` line body (`ssh-ed25519 AAAA…`). Pin it\ninstead of turning host verification off; it is minted for this sandbox and dies with it.",
            "type": "string"
          },
          "host_key_fingerprint": {
            "description": "`SHA256:…` of `host_key`, which is what `ssh` prints on a first connection.",
            "type": "string"
          },
          "idle_timeout_s": {
            "description": "Seconds of inactivity after which an open session is closed.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "key_id": {
            "description": "Identifier for the authorised key, for revoking it later.",
            "type": "string"
          },
          "proxy_command": {
            "description": "The `ProxyCommand` that carries the connection: `promigence sandbox ssh <id> --proxy`.",
            "type": "string"
          },
          "sandbox_id": {
            "description": "The sandbox this access is for.",
            "type": "string"
          },
          "ssh_command": {
            "description": "A complete `ssh` command line, for pasting.",
            "type": "string"
          },
          "token": {
            "description": "The short-lived credential the tunnel authenticates with. Shown once.",
            "type": "string"
          },
          "user": {
            "description": "The login name to use. It is the sandbox id: a key is authorised for one name only.",
            "type": "string"
          }
        },
        "required": [
          "sandbox_id",
          "key_id",
          "fingerprint",
          "user",
          "host",
          "token",
          "expires_at",
          "idle_timeout_s",
          "host_key",
          "host_key_fingerprint",
          "proxy_command",
          "ssh_command"
        ],
        "type": "object"
      },
      "SshAccessList": {
        "description": "What `GET /v1/sandboxes/:id/ssh` answers.",
        "properties": {
          "host_key": {
            "description": "Absent when the sandbox has never been asked for SSH access.",
            "type": [
              "string",
              "null"
            ]
          },
          "host_key_fingerprint": {
            "type": [
              "string",
              "null"
            ]
          },
          "idle_timeout_s": {
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "keys": {
            "items": {
              "$ref": "#/components/schemas/SshKey"
            },
            "type": "array"
          },
          "sandbox_id": {
            "type": "string"
          }
        },
        "required": [
          "sandbox_id",
          "keys",
          "idle_timeout_s"
        ],
        "type": "object"
      },
      "SshAccessRequest": {
        "additionalProperties": false,
        "description": "`POST /v1/sandboxes/{id}/ssh`.",
        "properties": {
          "idle_timeout_s": {
            "description": "Seconds an idle connection is kept.",
            "format": "uint64",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "public_key": {
            "description": "An OpenSSH public key line.",
            "type": "string"
          },
          "ttl_s": {
            "description": "Seconds the key is accepted.",
            "format": "uint64",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          }
        },
        "required": [
          "public_key"
        ],
        "type": "object"
      },
      "SshKey": {
        "description": "One authorised key, as `GET /v1/sandboxes/:id/ssh` lists them.",
        "properties": {
          "created_at": {
            "type": "string"
          },
          "expires_at": {
            "type": "string"
          },
          "fingerprint": {
            "type": "string"
          },
          "key_id": {
            "type": "string"
          },
          "token_active": {
            "description": "True while the access credential issued with this key is still valid.",
            "type": "boolean"
          },
          "user": {
            "type": "string"
          }
        },
        "required": [
          "key_id",
          "fingerprint",
          "user",
          "expires_at",
          "created_at",
          "token_active"
        ],
        "type": "object"
      },
      "SshRevoked": {
        "description": "What `DELETE /v1/sandboxes/:id/ssh/:key_id` answers.\n\n`revoked: false` is not an error: revoking is idempotent, and a caller retrying after a\ntimeout must not be told the retry failed.",
        "properties": {
          "key_id": {
            "type": "string"
          },
          "revoked": {
            "type": "boolean"
          },
          "sandbox_id": {
            "type": "string"
          }
        },
        "required": [
          "sandbox_id",
          "key_id",
          "revoked"
        ],
        "type": "object"
      },
      "StatusSummary": {
        "description": "`GET /v1/status` — 24 hours of synthetic check results plus each service's health. This is\nwhat the status page reads.",
        "properties": {
          "checks": {
            "$ref": "#/components/schemas/CheckWindow"
          },
          "generated_at": {
            "description": "RFC 3339.",
            "type": "string"
          },
          "service": {
            "type": "string"
          },
          "services": {
            "description": "`api`, then `sandboxes`.",
            "items": {
              "$ref": "#/components/schemas/ServiceStatus"
            },
            "type": "array"
          },
          "version": {
            "type": "string"
          }
        },
        "required": [
          "service",
          "generated_at",
          "version",
          "services",
          "checks"
        ],
        "type": "object"
      },
      "StdinAck": {
        "description": "The reply to `POST /v1/sandboxes/:id/execs/:exec_id/stdin`.",
        "properties": {
          "eof": {
            "description": "This call closed the input side.",
            "type": "boolean"
          },
          "exec_id": {
            "type": "string"
          },
          "ok": {
            "type": "boolean"
          },
          "sandbox_id": {
            "type": "string"
          },
          "written": {
            "description": "Bytes handed to the child's stdin by this call.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "ok",
          "sandbox_id",
          "exec_id",
          "written",
          "eof"
        ],
        "type": "object"
      },
      "TemplateDependencies": {
        "description": "What a template version has installed, read from the version itself when it was built: the\noperating system, every package by package manager (`dpkg`, `pip`, `npm`, `gem`, `cargo`,\n`apk`; a manager with nothing installed is absent), and each well-known tool's version line.",
        "properties": {
          "arch": {
            "type": "string"
          },
          "os": {
            "type": "string"
          },
          "packages": {
            "additionalProperties": {
              "items": {
                "$ref": "#/components/schemas/TemplatePackage"
              },
              "type": "array"
            },
            "type": "object"
          },
          "tools": {
            "additionalProperties": {
              "type": "string"
            },
            "type": "object"
          }
        },
        "required": [
          "os",
          "arch",
          "packages",
          "tools"
        ],
        "type": "object"
      },
      "TemplateDependencySummary": {
        "description": "A count of a template version's dependencies, for lists.",
        "properties": {
          "os": {
            "type": "string"
          },
          "packages": {
            "description": "Installed packages, every package manager together.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "tools": {
            "additionalProperties": {
              "type": "string"
            },
            "type": "object"
          }
        },
        "required": [
          "os",
          "packages",
          "tools"
        ],
        "type": "object"
      },
      "TemplateDetail": {
        "description": "`GET /v1/templates/:name` — one published template: its current version's full dependency list,\nits setup steps, and every published version.",
        "properties": {
          "category": {
            "type": "string"
          },
          "dependencies": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/TemplateDependencies"
              },
              {
                "type": "null"
              }
            ]
          },
          "image": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "published_at": {
            "type": [
              "string",
              "null"
            ]
          },
          "setup": {
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "snapshot_id": {
            "type": "string"
          },
          "summary": {
            "type": "string"
          },
          "tier": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "verify": {
            "type": "string"
          },
          "version": {
            "format": "int64",
            "type": "integer"
          },
          "versions": {
            "items": {
              "$ref": "#/components/schemas/TemplateVersionView"
            },
            "type": "array"
          }
        },
        "required": [
          "name",
          "title",
          "summary",
          "category",
          "version",
          "snapshot_id",
          "image",
          "tier",
          "verify",
          "setup",
          "versions"
        ],
        "type": "object"
      },
      "TemplateList": {
        "description": "`GET /v1/templates` — every published template.",
        "properties": {
          "templates": {
            "items": {
              "$ref": "#/components/schemas/TemplateSummary"
            },
            "type": "array"
          }
        },
        "required": [
          "templates"
        ],
        "type": "object"
      },
      "TemplatePackage": {
        "description": "One installed package of a template's dependency list.",
        "properties": {
          "name": {
            "type": "string"
          },
          "version": {
            "type": "string"
          }
        },
        "required": [
          "name",
          "version"
        ],
        "type": "object"
      },
      "TemplateSummary": {
        "description": "A published template (`GET /v1/templates`): a starting point to fork. `snapshot_id` is what to\nfork (`promigence fork --snapshot <id>`, or the template's name); `version` counts up each time\nthe template is updated.",
        "properties": {
          "category": {
            "description": "`base`, `language`, `starter`, `agent` or `benchmark`.",
            "type": "string"
          },
          "dependencies": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/TemplateDependencySummary"
              },
              {
                "type": "null"
              }
            ]
          },
          "image": {
            "description": "The image it starts from, pinned by digest.",
            "type": "string"
          },
          "name": {
            "description": "The name to fork it by.",
            "type": "string"
          },
          "published_at": {
            "description": "When this version was published, RFC 3339.",
            "type": [
              "string",
              "null"
            ]
          },
          "snapshot_id": {
            "type": "string"
          },
          "summary": {
            "type": "string"
          },
          "tier": {
            "description": "The sandbox shape it is built and forked at.",
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "verify": {
            "description": "The command whose success made this version ready.",
            "type": "string"
          },
          "version": {
            "format": "int64",
            "type": "integer"
          }
        },
        "required": [
          "name",
          "title",
          "summary",
          "category",
          "version",
          "snapshot_id",
          "image",
          "tier",
          "verify"
        ],
        "type": "object"
      },
      "TemplateVersionView": {
        "description": "One published version of a template, in its history.",
        "properties": {
          "current": {
            "description": "The version customers fork now.",
            "type": "boolean"
          },
          "notes": {
            "description": "What changed in this version.",
            "type": "string"
          },
          "published_at": {
            "type": [
              "string",
              "null"
            ]
          },
          "security": {
            "description": "This version fixes a security problem.",
            "type": "boolean"
          },
          "version": {
            "format": "int64",
            "type": "integer"
          }
        },
        "required": [
          "version",
          "notes",
          "security",
          "current"
        ],
        "type": "object"
      },
      "Totals": {
        "properties": {
          "aborted_by_client": {
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "cap_killed": {
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "completed": {
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "env_failed": {
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "env_verified": {
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "evidence_missing": {
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "expired": {
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "grader_failed": {
            "default": 0,
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "not_started": {
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "preempted": {
            "default": 0,
            "description": "Preemptible sandboxes stopped early, as preemptible runs can be. Its own counter and not\npart of `env_failed`: `env_failed: 8` says the environment failed eight times, and\n`preempted: 8` says something completely different about the same event.",
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "snapshot_failed": {
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "stopped_by_support": {
            "default": 0,
            "description": "Sandboxes Promigence support stopped (`stopped_by_support`), each with its reason. Its own\ncounter: not the customer's own kills (`aborted_by_client`) and not a failure.",
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "task_failed": {
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "env_verified",
          "completed",
          "task_failed",
          "env_failed",
          "snapshot_failed",
          "aborted_by_client",
          "expired",
          "cap_killed",
          "not_started",
          "evidence_missing"
        ],
        "type": "object"
      },
      "TrialLimits": {
        "description": "The limits the trial applies.",
        "properties": {
          "egress_gb_month": {
            "description": "Data out included each month, in GiB.",
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "max_concurrency": {
            "format": "uint32",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "max_sandbox_vcpus": {
            "format": "uint32",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "max_session_s": {
            "format": "uint64",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "smtp": {
            "description": "Whether outbound mail (port 25) is open for this organisation.",
            "type": "boolean"
          }
        },
        "required": [
          "smtp"
        ],
        "type": "object"
      },
      "TrialNotice": {
        "description": "A notice about the account, with what to do about it: the trial rules changing\n(`card_required_soon`, `card_required`), or a notice about the service (`service_notice`:\nplanned maintenance, an incident), which also carries `level`, `notice_id` and `ends_at`.",
        "properties": {
          "code": {
            "description": "`card_required_soon` | `card_required` | `service_notice`.",
            "type": "string"
          },
          "credits_remaining": {
            "description": "USD: the trial credits left (0 for an organisation that is not on the trial and is shown a\nservice notice).",
            "format": "double",
            "type": "number"
          },
          "docs": {
            "type": "string"
          },
          "effective_at": {
            "description": "RFC 3339: when the change takes effect, or when a service notice began.",
            "type": "string"
          },
          "ends_at": {
            "description": "RFC 3339: when a service notice ends; absent while it has no end.",
            "type": [
              "string",
              "null"
            ]
          },
          "fix": {
            "type": "string"
          },
          "level": {
            "description": "A service notice's level: `info` | `warning` | `critical`.",
            "type": [
              "string",
              "null"
            ]
          },
          "message": {
            "type": "string"
          },
          "notice_id": {
            "description": "A service notice's id.",
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "code",
          "effective_at",
          "credits_remaining",
          "message",
          "fix",
          "docs"
        ],
        "type": "object"
      },
      "TrialPolicy": {
        "description": "Whether, and from when, a card is required to start new work.",
        "properties": {
          "card_required_from": {
            "description": "RFC 3339; `null` while no date is set.",
            "type": [
              "string",
              "null"
            ]
          },
          "card_required_now": {
            "description": "True once a card is required right now.",
            "type": "boolean"
          },
          "mode": {
            "description": "`open` | `notice` | `card_required`.",
            "type": "string"
          },
          "notice_from": {
            "description": "RFC 3339; `null` while no date is set.",
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "mode",
          "card_required_now"
        ],
        "type": "object"
      },
      "TrialStatus": {
        "description": "The trial an organisation is on, and what is left of it.",
        "properties": {
          "card_on_file": {
            "type": "boolean"
          },
          "credits_available": {
            "description": "What a new run may count on.",
            "format": "double",
            "type": "number"
          },
          "credits_granted": {
            "description": "USD.",
            "format": "double",
            "type": "number"
          },
          "credits_remaining": {
            "format": "double",
            "type": "number"
          },
          "credits_reserved": {
            "description": "Committed to live work and not yet charged.",
            "format": "double",
            "type": "number"
          },
          "egress_gb_cap": {
            "description": "Data out included this month, in GiB: the plan's allowance. Above it, data out is billed,\nor stopped when the org cannot be billed (no card); `null` when the plan includes none.",
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "egress_gb_used": {
            "description": "Data out this month, in GiB.",
            "format": "double",
            "type": "number"
          },
          "egress_month": {
            "description": "The month the data-out counters are for, `YYYY-MM`.",
            "type": "string"
          },
          "limits": {
            "$ref": "#/components/schemas/TrialLimits"
          },
          "on_trial": {
            "description": "Trial rules apply: credit-gated, with trial limits.",
            "type": "boolean"
          },
          "policy": {
            "$ref": "#/components/schemas/TrialPolicy"
          }
        },
        "required": [
          "on_trial",
          "card_on_file",
          "credits_granted",
          "credits_remaining",
          "credits_reserved",
          "credits_available",
          "egress_gb_used",
          "egress_month",
          "limits",
          "policy"
        ],
        "type": "object"
      },
      "UpcomingInvoice": {
        "description": "The payment provider's estimate of the next invoice. Amounts are USD; each is `null` when\nthe provider did not state it.",
        "properties": {
          "amount_due": {
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "currency": {
            "type": [
              "string",
              "null"
            ]
          },
          "next_payment_attempt": {
            "description": "RFC 3339.",
            "type": [
              "string",
              "null"
            ]
          },
          "period_end": {
            "description": "RFC 3339.",
            "type": [
              "string",
              "null"
            ]
          },
          "period_start": {
            "description": "RFC 3339.",
            "type": [
              "string",
              "null"
            ]
          },
          "subtotal": {
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "total": {
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          }
        },
        "type": "object"
      },
      "UserView": {
        "description": "A user, as the sign-in and organisation routes report one.",
        "properties": {
          "created_at": {
            "description": "RFC 3339.",
            "type": "string"
          },
          "email": {
            "type": "string"
          },
          "email_verified": {
            "type": "boolean"
          },
          "provider": {
            "description": "The identity provider the user signed in with.",
            "type": "string"
          },
          "user_id": {
            "type": "string"
          }
        },
        "required": [
          "user_id",
          "email",
          "provider",
          "email_verified",
          "created_at"
        ],
        "type": "object"
      },
      "Verification": {
        "properties": {
          "concurrency": {
            "$ref": "#/components/schemas/Concurrency"
          },
          "disk_used_mib": {
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "egress": {
            "description": "When `true`, outbound network access was confirmed working at verification time.",
            "type": [
              "boolean",
              "null"
            ]
          },
          "fits_tier": {
            "description": "Advisory: smallest tier that would fit.",
            "type": "string"
          },
          "guards": {
            "items": {
              "$ref": "#/components/schemas/Guard"
            },
            "type": "array"
          },
          "output_digest": {
            "type": "string"
          },
          "peak_mem_mib": {
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "tier_disk_mib": {
            "description": "Tier disk in MiB; `disk_free_min_mib = tier_disk_mib − disk_used_mib − 512`.",
            "format": "uint64",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "tier_mem_mib": {
            "description": "Tier memory in MiB at build; `headroom_mib = tier_mem_mib − peak_mem_mib`.",
            "format": "uint64",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "verified_paths": {
            "items": {
              "$ref": "#/components/schemas/VerifiedPath"
            },
            "type": "array"
          },
          "verify_bin": {
            "description": "Binary the snapshot's `verify` needs (`bun`, `cargo`, …): must be executable on the\nsandbox's PATH or absolute. Checked before a fork is handed over.",
            "type": [
              "string",
              "null"
            ]
          },
          "verify_cold_ms": {
            "format": "double",
            "type": "number"
          },
          "verify_each_cmd": {
            "description": "The `verify_each` command, run verbatim through `sh -c` in `/work/repo` after the\nhand-over stamp; compared against `output_digest` and `verify_warm_first.cpu_ms`.\nFalls back to `provenance.verify.cmd` when absent.",
            "type": [
              "string",
              "null"
            ]
          },
          "verify_exit": {
            "format": "int32",
            "type": "integer"
          },
          "verify_warm": {
            "$ref": "#/components/schemas/WarmSteady",
            "description": "The verify command's steady warm time in the first fork (its third to fifth warm runs)."
          },
          "verify_warm_builder": {
            "$ref": "#/components/schemas/WarmSeries",
            "description": "Unchanged rerun in the builder."
          },
          "verify_warm_first": {
            "$ref": "#/components/schemas/WarmFirst",
            "description": "The first warm run of the verify command after the build — the `verify_each` baseline."
          }
        },
        "required": [
          "verify_exit",
          "verify_cold_ms",
          "verify_warm_builder",
          "verify_warm_first",
          "verify_warm",
          "output_digest",
          "guards",
          "peak_mem_mib",
          "disk_used_mib",
          "verified_paths",
          "fits_tier",
          "concurrency"
        ],
        "type": "object"
      },
      "VerifiedPath": {
        "properties": {
          "dir": {
            "type": "string"
          },
          "merkle_root": {
            "type": "string"
          }
        },
        "required": [
          "dir",
          "merkle_root"
        ],
        "type": "object"
      },
      "VerifyCmd": {
        "properties": {
          "allow_fast": {
            "type": "boolean"
          },
          "cmd": {
            "type": "string"
          }
        },
        "required": [
          "cmd",
          "allow_fast"
        ],
        "type": "object"
      },
      "VerifyRequest": {
        "anyOf": [
          {
            "type": "string"
          },
          {
            "$ref": "#/components/schemas/VerifySpec"
          }
        ],
        "description": "The verification command: a string, or `{cmd, allow_fast}`."
      },
      "VerifySpec": {
        "additionalProperties": false,
        "description": "The verification command, long form.",
        "properties": {
          "allow_fast": {
            "description": "Accept a verification run that finishes suspiciously fast.",
            "type": "boolean"
          },
          "cmd": {
            "type": "string"
          }
        },
        "required": [
          "cmd"
        ],
        "type": "object"
      },
      "ViaSecret": {
        "description": "One host-bound secret a sandbox holds, and the hosts it may be sent to.",
        "properties": {
          "hosts": {
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "secret": {
            "type": "string"
          }
        },
        "required": [
          "secret",
          "hosts"
        ],
        "type": "object"
      },
      "Visibility": {
        "enum": [
          "private",
          "public"
        ],
        "type": "string",
        "x-promigence-open-enum": true
      },
      "WarmFirst": {
        "properties": {
          "cpu_ms": {
            "format": "double",
            "type": "number"
          },
          "wall_ms": {
            "format": "double",
            "type": "number"
          }
        },
        "required": [
          "cpu_ms",
          "wall_ms"
        ],
        "type": "object"
      },
      "WarmMeasured": {
        "properties": {
          "baseline_cpu_ms": {
            "description": "`= verify_warm_first.cpu_ms`.",
            "format": "double",
            "type": "number"
          },
          "ratio": {
            "format": "double",
            "type": "number"
          },
          "verify_cpu_ms": {
            "format": "double",
            "type": "number"
          },
          "verify_ms": {
            "format": "double",
            "type": "number"
          }
        },
        "required": [
          "verify_ms",
          "verify_cpu_ms",
          "baseline_cpu_ms",
          "ratio"
        ],
        "type": "object"
      },
      "WarmSeries": {
        "properties": {
          "median_ms": {
            "format": "double",
            "type": "number"
          },
          "n": {
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "n",
          "median_ms"
        ],
        "type": "object"
      },
      "WarmSteady": {
        "properties": {
          "cpu_ms": {
            "format": "double",
            "type": "number"
          },
          "median_ms": {
            "format": "double",
            "type": "number"
          },
          "n": {
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "n",
          "median_ms",
          "cpu_ms"
        ],
        "type": "object"
      }
    }
  },
  "x-promigence-error-codes": {
    "fork_failed": {
      "category": "env",
      "http": 502,
      "exit": 3,
      "retryable": true,
      "message": "the sandbox could not be started",
      "fix": "Not billed. A run with a command is retried once automatically; otherwise re-run. If it repeats, re-verify the snapshot: `promigence snapshot verify {snapshot_id}`.",
      "unbilled": true
    },
    "start_timeout": {
      "category": "env",
      "http": 502,
      "exit": 3,
      "retryable": true,
      "message": "the sandbox did not answer its first command within {deadline_ms} ms",
      "fix": "Not billed. A run with a command is retried once automatically; otherwise start it again. If it keeps happening, tell support@promigence.ai the run id.",
      "unbilled": true
    },
    "readiness_failed": {
      "category": "env",
      "http": 502,
      "exit": 3,
      "retryable": true,
      "message": "the sandbox failed its readiness check",
      "fix": "Not billed: the sandbox was set aside before it was handed to you. A run with a command is retried once automatically; otherwise start it again. If it keeps failing, re-verify the snapshot: `promigence snapshot verify {snapshot_id}`.",
      "unbilled": true
    },
    "verify_too_slow": {
      "category": "env",
      "http": 502,
      "exit": 3,
      "retryable": true,
      "message": "the snapshot's verify step took longer in this sandbox than its limit allows",
      "fix": "Not billed. A run with a command is retried once automatically; otherwise start it again. If it keeps happening, re-verify the snapshot: `promigence snapshot verify {snapshot_id}`.",
      "unbilled": true
    },
    "verify_each_failed": {
      "category": "env",
      "http": 502,
      "exit": 3,
      "retryable": true,
      "message": "verify_each run failed in the fork (exit {exit_code}, digest {digest})",
      "fix": "Not billed. A run with a command is retried once automatically. If it repeats, the snapshot no longer reproduces: rebuild with `promigence snapshot create ...`.",
      "unbilled": true
    },
    "toolchain_mismatch": {
      "category": "env",
      "http": 502,
      "exit": 3,
      "retryable": true,
      "message": "toolchain check `{argv}` in the fork gave digest {got}, the verified snapshot recorded {expected}",
      "fix": "The fork's toolchain differs from the verified snapshot; not billed. Re-run; if it repeats, rebuild the snapshot.",
      "unbilled": true
    },
    "sandbox_unresponsive": {
      "category": "env",
      "http": 502,
      "exit": 3,
      "retryable": false,
      "message": "the sandbox stopped responding",
      "fix": "Billed for the time used, unless our side shows the cause was ours: then it is credited back (after a review if many are credited in one day), as the run report shows. Not retried automatically once your command has started. To run it again: `promigence run replay {run_id} --sandbox {sandbox_id}`. If you think the cause was ours, tell support@promigence.ai the run id.",
      "unbilled": true
    },
    "oom_within_tier": {
      "category": "env",
      "http": 502,
      "exit": 3,
      "retryable": false,
      "message": "the sandbox stopped on our side while within the tier's {tier_mib} MiB",
      "fix": "Our fault, not yours: credited back (at least the work lost since your last snapshot of this sandbox, up to 24 hours; a sandbox under 24 hours with no snapshot is not charged), after a review if many are credited in one day. Replay: `promigence run replay {run_id} --sandbox {sandbox_id}`.",
      "unbilled": true
    },
    "disk_full_within_tier": {
      "category": "env",
      "http": 502,
      "exit": 3,
      "retryable": false,
      "message": "the sandbox stopped on our side while within its {tier_disk_gib} GiB of disk",
      "fix": "Our fault, not yours: credited back (at least the work lost since your last snapshot of this sandbox, up to 24 hours; a sandbox under 24 hours with no snapshot is not charged), after a review if many are credited in one day. Replay: `promigence run replay {run_id} --sandbox {sandbox_id}`.",
      "unbilled": true
    },
    "sandbox_interrupted": {
      "category": "env",
      "http": 502,
      "exit": 3,
      "retryable": false,
      "message": "the sandbox was interrupted by a platform event",
      "fix": "Not caused by your work, and credited back: at least the work since your last snapshot of this sandbox, up to 24 hours; a sandbox under 24 hours with no snapshot is never charged. To run it again: `promigence run replay {run_id}`.",
      "unbilled": true
    },
    "integrity_mismatch": {
      "category": "env",
      "http": 502,
      "exit": 3,
      "retryable": false,
      "message": "the environment differs from the verified snapshot at {path}",
      "fix": "Not billed when we confirm the stored snapshot itself differs at that path; otherwise (only this sandbox's copy changed, or the check could not be made) the time used is billed. To run it again: `promigence run replay {run_id} --sandbox {sandbox_id}`; if it happens again, rebuild the snapshot.",
      "unbilled": true
    },
    "egress_unavailable": {
      "category": "env",
      "http": 502,
      "exit": 3,
      "retryable": false,
      "message": "the sandbox's outbound network was unavailable",
      "fix": "Not billed when we confirm the outage on our side, after a review if many are credited in one day; otherwise the time used is billed. To run it again: `promigence run replay {run_id}`.",
      "unbilled": true
    },
    "service_timeout": {
      "category": "env",
      "http": 504,
      "exit": 3,
      "retryable": false,
      "message": "the service's own time limit ({deadline_ms} ms) was reached before your command's timeout",
      "fix": "When the cause was ours (our service restarted), it is credited back: at least the work since your last snapshot of this sandbox, up to 24 hours. Otherwise the time used is billed. For long commands, set `timeout_ms`. To run it again: `promigence run replay {run_id} --sandbox {sandbox_id}`.",
      "unbilled": true
    },
    "preempted": {
      "category": "preempt",
      "http": 502,
      "exit": 3,
      "retryable": false,
      "message": "the preemptible sandbox was stopped early, as preemptible runs can be",
      "fix": "Our doing, not yours: credited back (at least the work lost since your last snapshot of this sandbox, up to 24 hours; a sandbox under 24 hours with no snapshot is never charged). This run asked to be preemptible, which is priced below the standard rate for exactly this reason. To run it again: `promigence run replay {run_id} --sandbox {sandbox_id}`; or run it without `preemptible` to pay the standard rate and not be stopped early.",
      "unbilled": false
    },
    "verify_did_not_cover": {
      "category": "snapshot",
      "http": 422,
      "exit": 4,
      "retryable": false,
      "message": "`{path}` is missing but was not under a verified path; the snapshot's verify did not cover it",
      "fix": "Billed: the environment matched what `verify` checked. Broaden `verify` (or `setup`) so the path is produced and covered, then `promigence snapshot create ...`.",
      "unbilled": false
    },
    "grader_failed": {
      "category": "grader",
      "http": 422,
      "exit": 3,
      "retryable": false,
      "message": "the grade could not be computed ({kind})",
      "fix": "Not a task failure. The time your grader ran is billed like the sandbox's own; a grade that failed on our side is not. Check that `grade.cmd` exits within `grade.timeout_ms` and that its output matches `grade.score` (exit | last_line_json | tap), then re-run.",
      "unbilled": false
    },
    "nonzero_exit": {
      "category": "task",
      "http": 422,
      "exit": 4,
      "retryable": false,
      "message": "command exited {exit_code}",
      "fix": "The environment was verified; the command failed. Inspect: `promigence exec output {exec_id}`.",
      "unbilled": false
    },
    "grade_not_passed": {
      "category": "task",
      "http": 422,
      "exit": 4,
      "retryable": false,
      "message": "the task completed and its grade did not pass (the grader exited {exit_code})",
      "fix": "Your grader failed the work; the task's command succeeded.",
      "unbilled": false
    },
    "task_timeout": {
      "category": "task",
      "http": 422,
      "exit": 4,
      "retryable": false,
      "message": "command exceeded timeout_ms={timeout_ms}",
      "fix": "Raise `--timeout` (billed per second used, so a longer timeout only costs what runs) or shorten the task.",
      "unbilled": false
    },
    "oom_over_tier": {
      "category": "task",
      "http": 422,
      "exit": 4,
      "retryable": false,
      "message": "the process was killed for exceeding the tier's {tier_mib} MiB of memory",
      "fix": "Rebuild the snapshot on a larger tier (`promigence snapshot create … --tier medium|large`; see `promigence agent-guide --section cost`) or reduce the task's memory.",
      "unbilled": false
    },
    "disk_over_tier": {
      "category": "task",
      "http": 422,
      "exit": 4,
      "retryable": false,
      "message": "the sandbox ran out of its {tier_disk_gib} GiB of disk",
      "fix": "Pick a larger tier or write less; the disk is sized to the tier quota.",
      "unbilled": false
    },
    "shutdown_by_task": {
      "category": "task",
      "http": 422,
      "exit": 4,
      "retryable": false,
      "message": "the sandbox shut itself down ({kind})",
      "fix": "Billed as the task's outcome: a command in the sandbox shut it down. Keep the task from doing that; if nothing in it should have, check what the agent ran.",
      "unbilled": false
    },
    "modified_by_task": {
      "category": "task",
      "http": 422,
      "exit": 4,
      "retryable": false,
      "message": "`{missing}` was removed or changed inside the sandbox; the snapshot's copy is intact",
      "fix": "Billed as the task's outcome: the sandbox started verified and something it ran deleted or changed `{path}`. Keep the task from modifying verified paths, or recreate what it needs first.",
      "unbilled": false
    },
    "cap_killed": {
      "category": "cap",
      "http": 402,
      "exit": 12,
      "retryable": false,
      "message": "sandbox killed when its accrued spend reached the spend cap ({spend_cap})",
      "fix": "The seconds it ran are billed, up to the cap. Raise `--cap` or `PATCH /sandboxes/:id` earlier.",
      "unbilled": false
    },
    "cap_exceeded": {
      "category": "cap",
      "http": 409,
      "exit": 5,
      "retryable": false,
      "message": "quote {max_cost} exceeds remaining spend cap {remaining}",
      "fix": "Raise `--cap`, lower `--count`/`--timeout`, or pass `--allow-partial` to launch what fits.",
      "unbilled": false
    },
    "cap_paused": {
      "category": "cap",
      "http": 402,
      "exit": 5,
      "retryable": false,
      "message": "sandbox {sandbox_id} is paused: its run reached its spend cap ({spend_cap})",
      "fix": "Its files and state are kept, and paused time is not billed. Raise the run's cap to go on: `promigence sandbox resume {sandbox_id} --cap <usd>` (`spend_cap` on POST /v1/sandboxes/{sandbox_id}/resume). Or end it: `promigence sandbox kill {sandbox_id}`.",
      "unbilled": false
    },
    "credits_paused": {
      "category": "cap",
      "http": 402,
      "exit": 5,
      "retryable": false,
      "message": "sandbox {sandbox_id} is paused: the organization's credits ran out",
      "fix": "Its files and state are kept, and paused time is not billed. Add a card to go on (owners: `promigence billing card`; members ask an owner), then resume it: `promigence sandbox resume {sandbox_id}`. Or end it: `promigence sandbox kill {sandbox_id}`.",
      "unbilled": false
    },
    "aborted_by_client": {
      "category": "other",
      "http": 200,
      "exit": 130,
      "retryable": false,
      "message": "sandbox killed by the client",
      "fix": "Nothing to fix; billed for the seconds used.",
      "unbilled": false
    },
    "stopped_by_support": {
      "category": "other",
      "http": 200,
      "exit": 12,
      "retryable": false,
      "message": "Stopped by Promigence support: {reason}",
      "fix": "Billed for the seconds it ran, as a kill is, unless support found the cause was on our side; then that time is credited back. Questions: tell support@promigence.ai the sandbox id.",
      "unbilled": false
    },
    "expired": {
      "category": "other",
      "http": 200,
      "exit": 12,
      "retryable": false,
      "message": "sandbox timeout reached (counted from hand-off)",
      "fix": "Raise `--timeout` if the task needs longer.",
      "unbilled": false
    },
    "not_started": {
      "category": "other",
      "http": 200,
      "exit": 12,
      "retryable": false,
      "message": "sandbox not started: outside the spend cap",
      "fix": "Raise `--cap`; with `--allow-partial` only what fits is launched.",
      "unbilled": true
    },
    "superseded": {
      "category": "other",
      "http": 200,
      "exit": 0,
      "retryable": false,
      "message": "attempt 1 superseded by a successful retry",
      "fix": "Nothing to fix; attempt 1 is unbilled.",
      "unbilled": true
    },
    "usage": {
      "category": "other",
      "http": 400,
      "exit": 2,
      "retryable": false,
      "message": "{detail}",
      "fix": "{detail}. See `promigence {command} --help`.",
      "unbilled": false
    },
    "internal": {
      "category": "other",
      "http": 500,
      "exit": 1,
      "retryable": false,
      "message": "internal error",
      "fix": "Not your fault. Re-run; if it repeats, tell support@promigence.ai the run or sandbox id and the time.",
      "unbilled": false
    },
    "auth": {
      "category": "other",
      "http": 401,
      "exit": 7,
      "retryable": false,
      "message": "missing or invalid API key",
      "fix": "Set PROMIGENCE_API_KEY or run `promigence auth login --from-env VAR`. No key yet: `promigence login` (sign in) or https://promigence.ai.",
      "unbilled": false
    },
    "forbidden": {
      "category": "other",
      "http": 403,
      "exit": 7,
      "retryable": false,
      "message": "{detail}",
      "fix": "Do what the message names: sign in (`promigence login`), use a full-access key (`promigence keys create`) or one from that org, or ask an owner.",
      "unbilled": false
    },
    "not_found": {
      "category": "other",
      "http": 404,
      "exit": 8,
      "retryable": false,
      "message": "{kind} `{id}` not found",
      "fix": "Check the id; aliases resolve in your org first, then public snapshots (`promigence examples`).",
      "unbilled": false
    },
    "unreachable": {
      "category": "other",
      "http": 503,
      "exit": 9,
      "retryable": false,
      "message": "cannot reach {url}",
      "fix": "Retry in a moment. If the API answered this, the fault is ours: if it repeats, email support@promigence.ai with the sandbox or run id. If the API itself did not answer, check PROMIGENCE_API_URL and your connection.",
      "unbilled": false
    },
    "rate_limited": {
      "category": "other",
      "http": 429,
      "exit": 10,
      "retryable": true,
      "message": "rate limited by {host}; retry after {retry_after_s} s",
      "fix": "Wait `Retry-After` seconds, then retry. If the limit is an image registry's, not this API's, a `registry_secret` holding your own login for it usually raises it. Otherwise lower concurrency (see `GET /me` limits).",
      "unbilled": false
    },
    "timeout": {
      "category": "other",
      "http": 504,
      "exit": 11,
      "retryable": true,
      "message": "wait of {wait_timeout} expired; nothing was killed",
      "fix": "Run the id-based command: `{next}`.",
      "unbilled": false
    },
    "not_verified": {
      "category": "other",
      "http": 409,
      "exit": 6,
      "retryable": false,
      "message": "snapshot {snapshot_id} is not verified (build {build_id}: {state})",
      "fix": "Wait for the build: `promigence snapshot status {build_id} --wait`.",
      "unbilled": false
    },
    "snapshot_incompatible": {
      "category": "other",
      "http": 409,
      "exit": 6,
      "retryable": false,
      "message": "snapshot {snapshot_id} can no longer run on the platform",
      "fix": "Nothing was started or billed. Rebuild it from the same source: POST /v1/snapshots (`promigence snapshot create`).",
      "unbilled": false
    },
    "storage_limit_reached": {
      "category": "other",
      "http": 409,
      "exit": 5,
      "retryable": false,
      "message": "{detail}",
      "fix": "Nothing was stored or charged, and nothing already stored was removed: delete what you no longer need, or move to a plan that keeps more.",
      "unbilled": false
    },
    "resume_unavailable": {
      "category": "env",
      "http": 503,
      "exit": 3,
      "retryable": true,
      "message": "sandbox {sandbox_id} is safe and still paused; it could not be resumed right now",
      "fix": "Your files are kept and nothing was billed. Retry in a minute. If it keeps happening, email support@promigence.ai with the sandbox id.",
      "unbilled": true
    },
    "sandbox_unreachable": {
      "category": "env",
      "http": 503,
      "exit": 3,
      "retryable": true,
      "message": "sandbox {sandbox_id} could not be reached just now; nothing was changed",
      "fix": "Not billed for this call, and the sandbox is as it was. Retry in a few seconds. If it keeps happening, email support@promigence.ai with the sandbox id.",
      "unbilled": true
    },
    "capacity_busy": {
      "category": "env",
      "http": 503,
      "exit": 3,
      "retryable": true,
      "message": "no capacity free right now",
      "fix": "Not billed, and nothing was started. Nothing was free in time: start it again in a few minutes, or lower `--count` to need fewer at once.",
      "unbilled": true
    },
    "region_at_capacity": {
      "category": "env",
      "http": 503,
      "exit": 3,
      "retryable": true,
      "message": "capacity is full right now",
      "fix": "Not billed, and nothing was started. Retry shortly, or lower `--count`.",
      "unbilled": true
    },
    "builder_unavailable": {
      "category": "env",
      "http": 503,
      "exit": 3,
      "retryable": true,
      "message": "new snapshots cannot be built right now",
      "fix": "Not billed, and nothing was stored. Nothing here can build at all, so this is not a busy queue and does not clear itself by waiting, and a smaller run does not help. Snapshots you have already built still run, so re-use one (`promigence snapshot list`). If you asked for a specific CPU, drop that and retry; otherwise retry shortly, and tell support@promigence.ai the time if it keeps happening.",
      "unbilled": true
    },
    "builder_busy": {
      "category": "env",
      "http": 503,
      "exit": 3,
      "retryable": true,
      "message": "snapshot builds are backed up; retry after {retry_after_s} s",
      "fix": "Not billed, and nothing was stored. Other builds are ahead of this one: submit it again in {retry_after_s} s. Builds already accepted keep their place in the queue and finish on their own (`promigence snapshot status <build_id> --wait`).",
      "unbilled": true
    },
    "overloaded": {
      "category": "env",
      "http": 503,
      "exit": 3,
      "retryable": true,
      "message": "the API is at capacity; retry in {retry_after_s} s",
      "fix": "Not billed, and nothing was started. Send the same request again in {retry_after_s} s; the SDKs and the CLI do this for you.",
      "unbilled": true
    },
    "tier_unavailable": {
      "category": "env",
      "http": 503,
      "exit": 3,
      "retryable": false,
      "message": "the {tier} tier ({vcpus} vCPU / {mem_gib} GiB) is not available yet",
      "fix": "Not billed. Use a smaller tier (`promigence snapshot create … --tier`; a fork runs on its snapshot's), or write to support@promigence.ai to have {tier} enabled for your account.",
      "unbilled": true
    },
    "snapshot_unavailable": {
      "category": "env",
      "http": 409,
      "exit": 3,
      "retryable": false,
      "message": "snapshot {snapshot_id} is no longer available: it could not be saved",
      "fix": "Not billed, and nothing was started. It cannot be started again: take a new snapshot of a running sandbox (`promigence sandbox snapshot <sandbox_id>`) or build it again (`promigence snapshot create ...`), then remove this one: `promigence snapshot delete {snapshot_id}`.",
      "unbilled": true
    },
    "capacity_limit": {
      "category": "env",
      "http": 409,
      "exit": 3,
      "retryable": false,
      "message": "{requested} {tier} sandboxes at once is more than one run can start at once; at most {max_at_once}",
      "fix": "Not billed; nothing started. Run at most {max_at_once} at once (lower `--count`), or use a smaller tier.",
      "unbilled": true
    },
    "build_timeout": {
      "category": "other",
      "http": 422,
      "exit": 4,
      "retryable": false,
      "message": "the build ran past its {limit_min}-minute limit",
      "fix": "Nothing was stored; the {limit_min} minutes it ran are billed. Shorten `setup` (at most 64 steps, {limit_min} minutes in all) or bake the slow part into the image.",
      "unbilled": false
    },
    "dockerfile_build_failed": {
      "category": "other",
      "http": 400,
      "exit": 2,
      "retryable": false,
      "message": "your image could not be built from the Dockerfile: {detail}",
      "fix": "Nothing was stored; the time the build ran is billed. Fix the Dockerfile (the lines above are the end of your own build output) and run `promigence snapshot create --dockerfile PATH ...` again.",
      "unbilled": false
    },
    "image_unresolvable": {
      "category": "other",
      "http": 422,
      "exit": 2,
      "retryable": false,
      "message": "`{image}` could not be resolved to a digest: {detail}",
      "fix": "Nothing was stored and nothing was billed. Check the name and tag; a private image needs `registry_secret` naming a stored secret that holds `user:password` (`promigence secrets set`). You can also pass the image already pinned as NAME@sha256:<digest>.",
      "unbilled": false
    },
    "registry_unavailable": {
      "category": "env",
      "http": 503,
      "exit": 3,
      "retryable": true,
      "message": "`{image}` could not be resolved to a digest because its registry did not answer usably: {detail}",
      "fix": "Not billed, and nothing was stored. Your image is not at fault: submit it again in {retry_after_s} s. Snapshots you have already built from it still run (`promigence snapshot list`).",
      "unbilled": true
    },
    "enoent": {
      "category": "other",
      "http": 404,
      "exit": 8,
      "retryable": false,
      "message": "`{argv0}` not found in the sandbox",
      "fix": "Check the command name; install the program in the image or in a setup step; for a shell builtin or a pipeline, run it through a shell: `-- sh -c '...'`.",
      "unbilled": false
    },
    "trial_credits_exhausted": {
      "category": "cap",
      "http": 402,
      "exit": 5,
      "retryable": false,
      "message": "trial credits left ({remaining}) do not cover this ({needed})",
      "fix": "Add a card to keep going (owners: `promigence billing card`, or POST /v1/billing/checkout; members ask an owner). Remaining credits are used first; running sandboxes finish.",
      "unbilled": false
    },
    "credit_unclaimed": {
      "category": "other",
      "http": 402,
      "exit": 5,
      "retryable": false,
      "message": "this account has free credit waiting to be claimed",
      "fix": "Claim it in your browser: `promigence credits claim` (owners; members ask an owner). Or add a card: `promigence billing card`. Nothing was started or charged.",
      "unbilled": false
    },
    "setup_required": {
      "category": "other",
      "http": 403,
      "exit": 7,
      "retryable": false,
      "message": "finish setting up your account before starting new work",
      "fix": "Open {setup_url} and answer the setup questions (under a minute), then run this again. Nothing was started or charged.",
      "unbilled": false
    },
    "card_required": {
      "category": "other",
      "http": 402,
      "exit": 5,
      "retryable": false,
      "message": "a card is required for new work since {effective_at}",
      "fix": "Add a card (owners: `promigence billing card`, or POST /v1/billing/checkout; members ask an owner). Your trial credits are kept and used first; reads and results stay available.",
      "unbilled": false
    },
    "billing_unavailable": {
      "category": "other",
      "http": 503,
      "exit": 5,
      "retryable": false,
      "message": "card payments are not open yet",
      "fix": "Nothing was charged. Your trial credits are kept and used first; for more credits, email support@promigence.ai.",
      "unbilled": false
    },
    "concurrency_limit": {
      "category": "other",
      "http": 409,
      "exit": 5,
      "retryable": false,
      "message": "{live} live + {requested} requested sandboxes is over your limit of {limit}",
      "fix": "Wait for sandboxes to end or lower `--count` (`--allow-partial` covers the spend cap only); a retry of the same request fails the same way. Trial orgs get {trial_limit}; to raise it, email support@promigence.ai.",
      "unbilled": false
    },
    "egress_cap_reached": {
      "category": "other",
      "http": 403,
      "exit": 5,
      "retryable": false,
      "message": "monthly data-out cap reached: {used_gb} of {cap_gb} GB",
      "fix": "Use `--network none` (still allowed) or wait for the 1st (UTC). For more data out a month, email support@promigence.ai.",
      "unbilled": false
    },
    "project_cap_reached": {
      "category": "cap",
      "http": 403,
      "exit": 5,
      "retryable": false,
      "message": "project {project} has {remaining} of its {limit} monthly cap left; this needs {needed}",
      "fix": "Ask for less (`--count`, `--cap`, a shorter extension), wait for the 1st (UTC), or have an owner raise it: `promigence project cap {project} <usd>`.",
      "unbilled": false
    },
    "spend_limit_reached": {
      "category": "cap",
      "http": 402,
      "exit": 5,
      "retryable": false,
      "message": "today's spend limit {limit} has {remaining} left; this needs {needed}",
      "fix": "Running sandboxes finish. The limit resets at 00:00 UTC and grows with each paid invoice; ask for less, or email support@promigence.ai.",
      "unbilled": false
    },
    "billing_hold": {
      "category": "other",
      "http": 402,
      "exit": 5,
      "retryable": false,
      "message": "new work is on hold: {reason}",
      "fix": "Running sandboxes finish. Owners: update the card with `promigence billing portal`; the hold lifts once the invoice is paid. For a disputed payment, write to support@promigence.ai.",
      "unbilled": false
    },
    "tier_over_plan": {
      "category": "other",
      "http": 403,
      "exit": 2,
      "retryable": false,
      "message": "the {tier} tier ({vcpus} vCPU) is over the {limit} vCPU per-sandbox limit of your {plan} plan",
      "fix": "Use a tier of at most {limit} vCPU (`promigence snapshot create … --tier {max_tier}` is the largest; a fork runs on its snapshot's), or move to a plan that allows it: `promigence billing portal`.",
      "unbilled": false
    },
    "network_host_refused": {
      "category": "other",
      "http": 403,
      "exit": 9,
      "retryable": false,
      "message": "{host} is not on this sandbox's allowed list, so the connection was refused",
      "fix": "Add it when you start the sandbox — `--allow {host}` — or drop `--allow` to let the sandbox reach anything. `promigence sandbox network <id>` lists everything that has been refused.",
      "unbilled": false
    },
    "network_policy_unsupported": {
      "category": "env",
      "http": 502,
      "exit": 3,
      "retryable": true,
      "message": "this sandbox asked to reach only {allow}, and that could not be applied",
      "fix": "Nothing ran and nothing was billed: the sandbox was discarded rather than started without the restriction you asked for. Re-run; if it repeats, tell support@promigence.ai the run id.",
      "unbilled": true
    },
    "secrets_in_snapshot": {
      "category": "other",
      "http": 409,
      "exit": 2,
      "retryable": false,
      "message": "sandbox {sandbox_id} was given a secret's value, so a snapshot of it can contain that value",
      "fix": "To take it anyway, pass `force: true` (`promigence sandbox snapshot {sandbox_id} --force`): that snapshot, and every sandbox started from it, can then contain the secret. Otherwise snapshot a sandbox that was never given a secret, and name the secret on the runs you start from it.",
      "unbilled": false
    },
    "secrets_unavailable": {
      "category": "env",
      "http": 503,
      "exit": 3,
      "retryable": true,
      "message": "secrets cannot be used right now",
      "fix": "Not billed, and nothing that names a secret was started. Runs, commands and terminals that name no secret are unaffected, and stored secrets can still be listed and deleted. Retry shortly; if it keeps happening, tell support@promigence.ai the time.",
      "unbilled": true
    },
    "secret_binding_unsupported": {
      "category": "env",
      "http": 502,
      "exit": 3,
      "retryable": true,
      "message": "a secret bound to a host could not be set up for this sandbox",
      "fix": "Nothing ran, nothing was billed, and the value never entered the sandbox. Re-run; if it repeats, tell support@promigence.ai the run id.",
      "unbilled": true
    },
    "idempotency_key_reused": {
      "category": "other",
      "http": 409,
      "exit": 2,
      "retryable": false,
      "message": "this Idempotency-Key was used for a different request",
      "fix": "Nothing was started. Use a new key for a new request; send the original request again to get its original answer.",
      "unbilled": false
    },
    "idempotency_key_in_use": {
      "category": "env",
      "http": 409,
      "exit": 3,
      "retryable": true,
      "message": "a request with this Idempotency-Key is still running",
      "fix": "Not billed; nothing new was started. Send the same request again in {retry_after_s} s for the first one's answer; the SDKs do this for you.",
      "unbilled": true
    },
    "repo_credentials_not_supported": {
      "category": "other",
      "http": 400,
      "exit": 2,
      "retryable": false,
      "message": "credentials in repository URLs are not accepted ({field})",
      "fix": "Nothing was built or billed. A repository URL never carries a credential. For a private repository, connect its host once for your organization (`promigence github connect` or `promigence gitlab connect`) and name it as `--repo owner/name` (`--repo gitlab:group/project`); a public one is named by its plain https:// URL, with no user name, password, token, query string or fragment in it.",
      "unbilled": false
    },
    "account_exists": {
      "category": "other",
      "http": 409,
      "exit": 7,
      "retryable": false,
      "message": "this email address has an account that signs in with {sign_in_with}",
      "fix": "Nothing was created. Sign in with {sign_in_with} instead: `{sign_in_command}`. If the browser signs you in with the method you just used, open the sign-in link in a private window. If you did not create that account, write to support@promigence.ai.",
      "unbilled": false
    },
    "invite_invalid": {
      "category": "other",
      "http": 403,
      "exit": 7,
      "retryable": false,
      "message": "this invite code is not valid",
      "fix": "Nothing was created. Check the code and try `promigence signup` again, or ask the person who invited you for a new code.",
      "unbilled": false
    },
    "invite_required": {
      "category": "other",
      "http": 403,
      "exit": 7,
      "retryable": false,
      "message": "new accounts need an invite code right now",
      "fix": "Nothing was created. Run `promigence signup` and enter your invite code when asked. If you already have an account, sign in with the method you used before (`promigence login`).",
      "unbilled": false
    },
    "key_expired": {
      "category": "other",
      "http": 401,
      "exit": 7,
      "retryable": false,
      "message": "this API key expired at {expired_at}",
      "fix": "Create a new key (`promigence keys create`, or sign in again with `promigence login`) and replace this one wherever it is used.",
      "unbilled": false
    },
    "account_blocked": {
      "category": "other",
      "http": 401,
      "exit": 7,
      "retryable": false,
      "message": "this account is blocked",
      "fix": "Write to support@promigence.ai to have it reviewed.",
      "unbilled": false
    }
  },
  "x-promigence-tiers": {
    "xsmall": {
      "vcpus": 1,
      "mem_gib": 1,
      "disk_gib": 10,
      "sellable": true
    },
    "small": {
      "vcpus": 2,
      "mem_gib": 4,
      "disk_gib": 10,
      "sellable": true
    },
    "medium": {
      "vcpus": 4,
      "mem_gib": 16,
      "disk_gib": 20,
      "sellable": true
    },
    "large-16": {
      "vcpus": 8,
      "mem_gib": 16,
      "disk_gib": 40,
      "sellable": true
    },
    "large": {
      "vcpus": 8,
      "mem_gib": 32,
      "disk_gib": 40,
      "sellable": true
    },
    "xlarge": {
      "vcpus": 16,
      "mem_gib": 32,
      "disk_gib": 80,
      "sellable": true
    },
    "2xlarge": {
      "vcpus": 32,
      "mem_gib": 64,
      "disk_gib": 160,
      "sellable": true
    }
  },
  "x-promigence-generated": {
    "do_not_edit": "Generated file. Do not edit by hand."
  },
  "x-promigence-digest": "f50a7849a07626f3c9e6110fdce9af19"
}
