{
  "openapi": "3.1.0",
  "info": {
    "title": "Vestra API",
    "version": "1.0.0",
    "description": "Give each of your users Bash inside your own product. You name them with your own ids; each one gets a real Bash with a computer, apps, memory, files and approvals. Your company has a Bash of its own too.\n\n## Quickstart\n\n1. **Authenticate.** Every call carries your key: `Authorization: Bearer vk_test_...`. Test keys run real, capped work on your test wallet; live keys run your live deployment.\n2. **Name your user.** Send your own id for the person as `user_id`; Bash creates the user the first time it sees the id. Leave `user_id` out to ask your company's own Bash. `POST /v1/users` sets a name or a default deployment first, if you want.\n3. **Ask.** `POST /v1/conversations` with `{ \"user_id\": \"traveller-42\", \"message\": \"...\" }`. Bash answers on the spot, acts in apps, calls your tools, or starts work on its computer. Add `\"stream\": true` to get this turn's events as they happen; the stream ends when the turn settles.\n4. **Follow the stream.** `GET /v1/conversations/{conversation_id}/events` is one resumable stream of replies, work, approvals, tool calls and files. Resume with `Last-Event-ID`.\n5. **Answer.** When Bash waits on you it sends `interaction.created`: an approval, a question, a hand-off, or a call to one of your tools. Answer any of them with `POST /v1/interactions/{interaction_id}/answer`. A money or account approval needs `present_user: true`, and so does the yes to a company action (a tool of your MCP servers, or a function of yours that is not read-only or run without asking).\n6. **Receive webhooks.** Register `POST /v1/webhooks`. Every call is signed with `Vestra-Signature: t=<unix seconds>,v1=<hmac>`; verify it before you trust the body.\n7. **Schedule it.** `POST /v1/routines` with `{ \"user_id\": \"traveller-42\", \"ask\": \"Check my trains for tomorrow\", \"every\": \"weekday at 08:00\" }`. Plain words, read in the user's time zone; the answer says the cron and the next run.\n8. **Show Bash in your app.** `POST /v1/sessions` with `{ \"user_id\": \"traveller-42\", \"chat\": true }` answers a 15 minute token and a page `url` for an iframe (or to open on its own). The token reaches only that user's conversation, never money, and a `DELETE` ends it at once.\n\n## Samples\n\n- `examples/trip-rescue`: this quickstart as a runnable script.\n- `examples/mock-travel-mcp`: a small travel MCP server (search, pnr_status, book, cancel) to plug in as your own tools.\n\n## SDKs and guides\n\nThe TypeScript SDK (`@vestra/sdk`) is organized by the card: `vestra.user(id).ask(...)`, typed events, and your tools as plain functions. The quickstart, and a page for every line of the card, are on [the developer site](/developers).\n"
  },
  "servers": [
    {
      "url": "https://api.vestra.ai",
      "description": "Production"
    },
    {
      "url": "https://api-staging.vestra.ai",
      "description": "Staging"
    }
  ],
  "security": [
    {
      "apiKey": []
    }
  ],
  "tags": [
    {
      "name": "Account"
    },
    {
      "name": "Users"
    },
    {
      "name": "Conversations"
    },
    {
      "name": "Work"
    },
    {
      "name": "Interactions"
    },
    {
      "name": "Files"
    },
    {
      "name": "Connected apps"
    },
    {
      "name": "MCP servers and secrets"
    },
    {
      "name": "Skills"
    },
    {
      "name": "Notebooks"
    },
    {
      "name": "Memory"
    },
    {
      "name": "Deployments"
    },
    {
      "name": "Tests"
    },
    {
      "name": "Computer setup"
    },
    {
      "name": "Routines"
    },
    {
      "name": "Batches"
    },
    {
      "name": "Webhooks and events"
    },
    {
      "name": "Sessions"
    },
    {
      "name": "MCP server"
    },
    {
      "name": "A2A"
    },
    {
      "name": "Contract"
    }
  ],
  "paths": {
    "/v1/me": {
      "get": {
        "operationId": "getMe",
        "summary": "Who is calling: the company, the key, and whether it is test or live.",
        "tags": [
          "Account"
        ],
        "x-vestra-line": "keys",
        "x-vestra-scope": "any",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "type": "string",
                      "const": "me",
                      "description": "Always `me`."
                    },
                    "org": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "Your company account's id.",
                          "examples": [
                            "org_2f8k"
                          ]
                        },
                        "name": {
                          "type": "string",
                          "description": "Your company's name."
                        },
                        "status": {
                          "type": "string",
                          "description": "`active` while the account works. Any other value means it is switched off, and calls answer 403 `org_disabled`."
                        }
                      },
                      "required": [
                        "id",
                        "name",
                        "status"
                      ],
                      "description": "The company account the call acts for."
                    },
                    "mode": {
                      "type": "string",
                      "enum": [
                        "live",
                        "test"
                      ],
                      "description": "`live` or `test`: the mode of the key (or console session) in use. A test key sees only test users, test deployments and test money."
                    },
                    "key": {
                      "anyOf": [
                        {
                          "type": "object",
                          "properties": {
                            "id": {
                              "type": "string",
                              "description": "The key's id.",
                              "examples": [
                                "key_8f2k"
                              ]
                            },
                            "name": {
                              "anyOf": [
                                {
                                  "type": "string"
                                },
                                {
                                  "type": "null"
                                }
                              ],
                              "description": "The name you gave the key; null when it has none."
                            },
                            "last4": {
                              "type": "string",
                              "description": "The last four characters of the key's secret, to tell keys apart."
                            }
                          },
                          "required": [
                            "id",
                            "name",
                            "last4"
                          ]
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The API key in use; null when the call comes from a console session."
                    },
                    "member": {
                      "anyOf": [
                        {
                          "type": "object",
                          "properties": {
                            "role": {
                              "type": "string",
                              "enum": [
                                "owner",
                                "admin",
                                "developer"
                              ],
                              "description": "Your role in the company: `owner`, `admin` or `developer`."
                            }
                          },
                          "required": [
                            "role"
                          ]
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Who is signed in to the console; null when the call uses an API key."
                    }
                  },
                  "required": [
                    "object",
                    "org",
                    "mode",
                    "key",
                    "member"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/org": {
      "get": {
        "operationId": "getOrg",
        "summary": "The company account: name, status, the wallet in billed dollars, day and month caps, alert thresholds, allowed return URLs, allowed embed origins, default deployment.",
        "tags": [
          "Account"
        ],
        "x-vestra-line": "keys",
        "x-vestra-scope": "admin",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "The company account's id.",
                      "examples": [
                        "org_2f8k"
                      ]
                    },
                    "object": {
                      "type": "string",
                      "const": "org",
                      "description": "Always `org`."
                    },
                    "name": {
                      "type": "string",
                      "description": "The company's name."
                    },
                    "status": {
                      "type": "string",
                      "description": "`active` while the account works. Any other value means it is switched off, and calls answer 403 `org_disabled`."
                    },
                    "mode": {
                      "type": "string",
                      "enum": [
                        "live",
                        "test"
                      ],
                      "description": "The mode these settings and this wallet belong to: `live` or `test`, the mode of the key in use."
                    },
                    "allowed_return_urls": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Where a connect link may send a person back to (`return_url`). Empty: no return URL is allowed."
                    },
                    "allowed_embed_origins": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "The https origins whose pages may show Bash in an iframe, and open a voice call."
                    },
                    "default_deployment": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The deployment a conversation runs when neither it nor its user names one; null: Bash as it comes, with no deployment of yours."
                    },
                    "require_user": {
                      "type": "boolean",
                      "description": "When true, a request that names no `user_id` answers 400 `user_required` instead of reaching the company's own Bash."
                    },
                    "memory_panel": {
                      "type": "boolean",
                      "description": "Whether a session may show the user what Bash remembers (POST /v1/sessions with `memory: true`). Off until you turn it on."
                    },
                    "memory_mode": {
                      "type": "string",
                      "enum": [
                        "vestra",
                        "customer",
                        "none"
                      ],
                      "description": "Who keeps what Bash remembers about each user, unless a deployment says otherwise: `vestra` (Bash keeps it), `customer` (your side keeps it, at `memory_endpoint`) or `none`."
                    },
                    "memory_endpoint": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "With `memory_mode: customer`, the https URL Bash asks for what to remember about a user; null otherwise."
                    },
                    "otlp_endpoint": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Where Bash sends its traces, as OpenTelemetry (OTLP over HTTP); null: none are sent."
                    },
                    "otlp_headers_secret": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The name of your secret that holds the headers sent with each trace; its value is never returned. Null: none."
                    },
                    "balance_usd": {
                      "type": "number",
                      "description": "This mode's wallet, in billed US dollars, up to 5 decimals. Work stops with 402 `wallet_empty` when it runs out."
                    },
                    "caps": {
                      "type": "object",
                      "properties": {
                        "org_daily_usd": {
                          "anyOf": [
                            {
                              "type": "number",
                              "minimum": 0,
                              "maximum": 1000000
                            },
                            {
                              "type": "null"
                            }
                          ],
                          "description": "The company's spending cap per day (UTC), in US dollars, across all its users; null: none, up to the account's ceiling."
                        },
                        "user_daily_usd": {
                          "anyOf": [
                            {
                              "type": "number",
                              "minimum": 0,
                              "maximum": 1000000
                            },
                            {
                              "type": "null"
                            }
                          ],
                          "description": "The default cap per user per day (UTC), in US dollars; a user's own `spend_cap_usd` wins. Null: none."
                        },
                        "max_org_daily_usd": {
                          "type": "number",
                          "minimum": 0,
                          "maximum": 1000000,
                          "description": "The highest the company's daily cap may be set, in US dollars. Ask Vestra to raise it."
                        },
                        "org_monthly_usd": {
                          "anyOf": [
                            {
                              "type": "number",
                              "minimum": 0,
                              "maximum": 1000000
                            },
                            {
                              "type": "null"
                            }
                          ],
                          "description": "The company's cap per calendar month (UTC), in US dollars. Null (the default): none."
                        },
                        "user_monthly_usd": {
                          "anyOf": [
                            {
                              "type": "number",
                              "minimum": 0,
                              "maximum": 1000000
                            },
                            {
                              "type": "null"
                            }
                          ],
                          "description": "The default cap per user per calendar month (UTC), in US dollars; a user's own `monthly_cap_usd` wins. Null (the default): none."
                        }
                      },
                      "required": [
                        "org_daily_usd",
                        "user_daily_usd",
                        "max_org_daily_usd",
                        "org_monthly_usd",
                        "user_monthly_usd"
                      ],
                      "description": "This mode's spending caps, for the company and per user, per day and per month."
                    },
                    "usage_alerts": {
                      "type": "object",
                      "properties": {
                        "thresholds": {
                          "maxItems": 5,
                          "type": "array",
                          "items": {
                            "type": "integer",
                            "minimum": 1,
                            "maximum": 100
                          },
                          "description": "Percents of a cap at which `usage.threshold_reached` fires; reaching 100 always fires `usage.cap_reached`."
                        }
                      },
                      "required": [
                        "thresholds"
                      ],
                      "description": "When Bash tells your webhooks that spend is nearing a cap."
                    },
                    "created_at": {
                      "type": "string",
                      "description": "When the account was made, as an ISO 8601 date and time in UTC."
                    }
                  },
                  "required": [
                    "id",
                    "object",
                    "name",
                    "status",
                    "mode",
                    "allowed_return_urls",
                    "allowed_embed_origins",
                    "default_deployment",
                    "require_user",
                    "memory_panel",
                    "memory_mode",
                    "memory_endpoint",
                    "otlp_endpoint",
                    "otlp_headers_secret",
                    "balance_usd",
                    "caps",
                    "usage_alerts",
                    "created_at"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "patchOrg",
        "summary": "Change the name, allowed return URLs, allowed embed origins, default deployment or default memory mode.",
        "tags": [
          "Account"
        ],
        "x-vestra-line": "keys",
        "x-vestra-scope": "admin",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "The company account's id.",
                      "examples": [
                        "org_2f8k"
                      ]
                    },
                    "object": {
                      "type": "string",
                      "const": "org",
                      "description": "Always `org`."
                    },
                    "name": {
                      "type": "string",
                      "description": "The company's name."
                    },
                    "status": {
                      "type": "string",
                      "description": "`active` while the account works. Any other value means it is switched off, and calls answer 403 `org_disabled`."
                    },
                    "mode": {
                      "type": "string",
                      "enum": [
                        "live",
                        "test"
                      ],
                      "description": "The mode these settings and this wallet belong to: `live` or `test`, the mode of the key in use."
                    },
                    "allowed_return_urls": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Where a connect link may send a person back to (`return_url`). Empty: no return URL is allowed."
                    },
                    "allowed_embed_origins": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "The https origins whose pages may show Bash in an iframe, and open a voice call."
                    },
                    "default_deployment": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The deployment a conversation runs when neither it nor its user names one; null: Bash as it comes, with no deployment of yours."
                    },
                    "require_user": {
                      "type": "boolean",
                      "description": "When true, a request that names no `user_id` answers 400 `user_required` instead of reaching the company's own Bash."
                    },
                    "memory_panel": {
                      "type": "boolean",
                      "description": "Whether a session may show the user what Bash remembers (POST /v1/sessions with `memory: true`). Off until you turn it on."
                    },
                    "memory_mode": {
                      "type": "string",
                      "enum": [
                        "vestra",
                        "customer",
                        "none"
                      ],
                      "description": "Who keeps what Bash remembers about each user, unless a deployment says otherwise: `vestra` (Bash keeps it), `customer` (your side keeps it, at `memory_endpoint`) or `none`."
                    },
                    "memory_endpoint": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "With `memory_mode: customer`, the https URL Bash asks for what to remember about a user; null otherwise."
                    },
                    "otlp_endpoint": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Where Bash sends its traces, as OpenTelemetry (OTLP over HTTP); null: none are sent."
                    },
                    "otlp_headers_secret": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The name of your secret that holds the headers sent with each trace; its value is never returned. Null: none."
                    },
                    "balance_usd": {
                      "type": "number",
                      "description": "This mode's wallet, in billed US dollars, up to 5 decimals. Work stops with 402 `wallet_empty` when it runs out."
                    },
                    "caps": {
                      "type": "object",
                      "properties": {
                        "org_daily_usd": {
                          "anyOf": [
                            {
                              "type": "number",
                              "minimum": 0,
                              "maximum": 1000000
                            },
                            {
                              "type": "null"
                            }
                          ],
                          "description": "The company's spending cap per day (UTC), in US dollars, across all its users; null: none, up to the account's ceiling."
                        },
                        "user_daily_usd": {
                          "anyOf": [
                            {
                              "type": "number",
                              "minimum": 0,
                              "maximum": 1000000
                            },
                            {
                              "type": "null"
                            }
                          ],
                          "description": "The default cap per user per day (UTC), in US dollars; a user's own `spend_cap_usd` wins. Null: none."
                        },
                        "max_org_daily_usd": {
                          "type": "number",
                          "minimum": 0,
                          "maximum": 1000000,
                          "description": "The highest the company's daily cap may be set, in US dollars. Ask Vestra to raise it."
                        },
                        "org_monthly_usd": {
                          "anyOf": [
                            {
                              "type": "number",
                              "minimum": 0,
                              "maximum": 1000000
                            },
                            {
                              "type": "null"
                            }
                          ],
                          "description": "The company's cap per calendar month (UTC), in US dollars. Null (the default): none."
                        },
                        "user_monthly_usd": {
                          "anyOf": [
                            {
                              "type": "number",
                              "minimum": 0,
                              "maximum": 1000000
                            },
                            {
                              "type": "null"
                            }
                          ],
                          "description": "The default cap per user per calendar month (UTC), in US dollars; a user's own `monthly_cap_usd` wins. Null (the default): none."
                        }
                      },
                      "required": [
                        "org_daily_usd",
                        "user_daily_usd",
                        "max_org_daily_usd",
                        "org_monthly_usd",
                        "user_monthly_usd"
                      ],
                      "description": "This mode's spending caps, for the company and per user, per day and per month."
                    },
                    "usage_alerts": {
                      "type": "object",
                      "properties": {
                        "thresholds": {
                          "maxItems": 5,
                          "type": "array",
                          "items": {
                            "type": "integer",
                            "minimum": 1,
                            "maximum": 100
                          },
                          "description": "Percents of a cap at which `usage.threshold_reached` fires; reaching 100 always fires `usage.cap_reached`."
                        }
                      },
                      "required": [
                        "thresholds"
                      ],
                      "description": "When Bash tells your webhooks that spend is nearing a cap."
                    },
                    "created_at": {
                      "type": "string",
                      "description": "When the account was made, as an ISO 8601 date and time in UTC."
                    }
                  },
                  "required": [
                    "id",
                    "object",
                    "name",
                    "status",
                    "mode",
                    "allowed_return_urls",
                    "allowed_embed_origins",
                    "default_deployment",
                    "require_user",
                    "memory_panel",
                    "memory_mode",
                    "memory_endpoint",
                    "otlp_endpoint",
                    "otlp_headers_secret",
                    "balance_usd",
                    "caps",
                    "usage_alerts",
                    "created_at"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "description": "The company's name, 1 to 200 characters.",
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 200
                  },
                  "allowed_return_urls": {
                    "description": "Where a connect link may send a person back to; replaces the whole list. At most 20.",
                    "examples": [
                      [
                        "https://app.example.com/connected"
                      ]
                    ],
                    "maxItems": 20,
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uri"
                    }
                  },
                  "allowed_embed_origins": {
                    "description": "The https origins whose pages may show Bash in an iframe; replaces the whole list. At most 20.",
                    "examples": [
                      [
                        "https://app.example.com"
                      ]
                    ],
                    "maxItems": 20,
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uri"
                    }
                  },
                  "default_deployment": {
                    "description": "The deployment a conversation runs when it names none, by name or `dep_` id; null clears it.",
                    "anyOf": [
                      {
                        "type": "string",
                        "minLength": 1
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "require_user": {
                    "description": "True: every request must name a `user_id`, and none reaches the company's own Bash.",
                    "type": "boolean"
                  },
                  "memory_panel": {
                    "description": "True: a session may show the user what Bash remembers.",
                    "type": "boolean"
                  },
                  "memory_mode": {
                    "description": "Who keeps what Bash remembers: `vestra`, `customer` (send `memory_endpoint` too) or `none`.",
                    "type": "string",
                    "enum": [
                      "vestra",
                      "customer",
                      "none"
                    ]
                  },
                  "memory_endpoint": {
                    "description": "With `memory_mode: customer`, the https URL Bash asks for what to remember; null clears it.",
                    "anyOf": [
                      {
                        "type": "string",
                        "format": "uri"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "otlp_endpoint": {
                    "description": "Where to send traces, as OpenTelemetry over HTTP; null stops them.",
                    "anyOf": [
                      {
                        "type": "string",
                        "format": "uri"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "otlp_headers_secret": {
                    "description": "The name of one of your secrets (PUT /v1/secrets/{name}) whose value is a JSON object of header names to values, sent with each trace; null clears it.",
                    "examples": [
                      "OTLP_HEADERS"
                    ],
                    "anyOf": [
                      {
                        "type": "string",
                        "pattern": "^[A-Z][A-Z0-9_]{0,63}$"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/keys": {
      "get": {
        "operationId": "getKeys",
        "summary": "List keys. Only the last four characters are ever shown again.",
        "tags": [
          "Account"
        ],
        "x-vestra-line": "keys",
        "x-vestra-scope": "admin",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "The key's id.",
                            "examples": [
                              "key_8f2k"
                            ]
                          },
                          "object": {
                            "type": "string",
                            "const": "api_key",
                            "description": "Always `api_key`."
                          },
                          "mode": {
                            "type": "string",
                            "enum": [
                              "live",
                              "test"
                            ],
                            "description": "`live` or `test`: what the key reaches. A test key sees only test users, test deployments and test money."
                          },
                          "name": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "The name you gave it; null when it has none."
                          },
                          "prefix": {
                            "type": "string",
                            "description": "The start of the secret, to tell keys apart: `vk_live_` or `vk_test_` and a few characters.",
                            "examples": [
                              "vk_test_8f2k"
                            ]
                          },
                          "last4": {
                            "type": "string",
                            "description": "The last four characters of the secret."
                          },
                          "scopes": {
                            "type": "array",
                            "items": {
                              "type": "string",
                              "enum": [
                                "all",
                                "runtime",
                                "setup",
                                "admin"
                              ]
                            },
                            "description": "What the key may call: `all`, or any of `runtime` (conversations, work, routines, connected apps, files, memory, usage), `setup` (deployments, tests, secrets) and `admin` (users and keys)."
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "active",
                              "expiring",
                              "expired",
                              "revoked"
                            ],
                            "description": "`active`: works, with no end. `expiring`: works until `expires_at` (a rolled key in its grace period, or one made to expire). `expired` or `revoked`: refused."
                          },
                          "created_at": {
                            "type": "string",
                            "description": "When it was made, as an ISO 8601 date and time in UTC."
                          },
                          "last_used_at": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "When it last made a call; null when it never has."
                          },
                          "expires_at": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "When it stops working; null when it never does."
                          },
                          "revoked_at": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "When it was revoked; null while it is not."
                          }
                        },
                        "required": [
                          "id",
                          "object",
                          "mode",
                          "name",
                          "prefix",
                          "last4",
                          "scopes",
                          "status",
                          "created_at",
                          "last_used_at",
                          "expires_at",
                          "revoked_at"
                        ]
                      },
                      "description": "The items on this page."
                    },
                    "next_cursor": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Send it as `cursor` for the next page; null on the last page."
                    }
                  },
                  "required": [
                    "data",
                    "next_cursor"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "postKeys",
        "summary": "Create a test or live key. The full key is shown once.",
        "tags": [
          "Account"
        ],
        "x-vestra-line": "keys",
        "x-vestra-scope": "admin",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [],
        "responses": {
          "201": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "The key's id.",
                      "examples": [
                        "key_8f2k"
                      ]
                    },
                    "object": {
                      "type": "string",
                      "const": "api_key",
                      "description": "Always `api_key`."
                    },
                    "mode": {
                      "type": "string",
                      "enum": [
                        "live",
                        "test"
                      ],
                      "description": "`live` or `test`: what the key reaches. A test key sees only test users, test deployments and test money."
                    },
                    "name": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The name you gave it; null when it has none."
                    },
                    "prefix": {
                      "type": "string",
                      "description": "The start of the secret, to tell keys apart: `vk_live_` or `vk_test_` and a few characters.",
                      "examples": [
                        "vk_test_8f2k"
                      ]
                    },
                    "last4": {
                      "type": "string",
                      "description": "The last four characters of the secret."
                    },
                    "scopes": {
                      "type": "array",
                      "items": {
                        "type": "string",
                        "enum": [
                          "all",
                          "runtime",
                          "setup",
                          "admin"
                        ]
                      },
                      "description": "What the key may call: `all`, or any of `runtime` (conversations, work, routines, connected apps, files, memory, usage), `setup` (deployments, tests, secrets) and `admin` (users and keys)."
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "active",
                        "expiring",
                        "expired",
                        "revoked"
                      ],
                      "description": "`active`: works, with no end. `expiring`: works until `expires_at` (a rolled key in its grace period, or one made to expire). `expired` or `revoked`: refused."
                    },
                    "created_at": {
                      "type": "string",
                      "description": "When it was made, as an ISO 8601 date and time in UTC."
                    },
                    "last_used_at": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "When it last made a call; null when it never has."
                    },
                    "expires_at": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "When it stops working; null when it never does."
                    },
                    "revoked_at": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "When it was revoked; null while it is not."
                    },
                    "secret": {
                      "type": "string",
                      "description": "The whole key. It is shown this once: store it now, as Vestra keeps only its hash.",
                      "examples": [
                        "vk_test_..."
                      ]
                    }
                  },
                  "required": [
                    "id",
                    "object",
                    "mode",
                    "name",
                    "prefix",
                    "last4",
                    "scopes",
                    "status",
                    "created_at",
                    "last_used_at",
                    "expires_at",
                    "revoked_at",
                    "secret"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "description": "A name for the key, to tell it apart later, up to 100 characters.",
                    "examples": [
                      "production"
                    ],
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100
                  },
                  "scopes": {
                    "description": "What it may call: `all` alone, or 1 to 3 of `runtime`, `setup` and `admin`. Absent: `all`. A key only gives the scopes it has.",
                    "examples": [
                      [
                        "runtime"
                      ]
                    ],
                    "minItems": 1,
                    "maxItems": 3,
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "all",
                        "runtime",
                        "setup",
                        "admin"
                      ]
                    }
                  },
                  "expires_at": {
                    "description": "When the key stops working, an ISO 8601 date and time in the future. Absent: never.",
                    "type": "string",
                    "format": "date-time",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/keys/{key_id}/roll": {
      "post": {
        "operationId": "postKeysByKeyIdRoll",
        "summary": "Replace a key. The old one keeps working for a grace period you choose, then stops.",
        "tags": [
          "Account"
        ],
        "x-vestra-line": "keys",
        "x-vestra-scope": "admin",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "key_id",
            "in": "path",
            "required": true,
            "description": "The API key's id (`key_...`).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "type": "string",
                      "const": "api_key_roll",
                      "description": "Always `api_key_roll`."
                    },
                    "key": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "The key's id.",
                          "examples": [
                            "key_8f2k"
                          ]
                        },
                        "object": {
                          "type": "string",
                          "const": "api_key",
                          "description": "Always `api_key`."
                        },
                        "mode": {
                          "type": "string",
                          "enum": [
                            "live",
                            "test"
                          ],
                          "description": "`live` or `test`: what the key reaches. A test key sees only test users, test deployments and test money."
                        },
                        "name": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ],
                          "description": "The name you gave it; null when it has none."
                        },
                        "prefix": {
                          "type": "string",
                          "description": "The start of the secret, to tell keys apart: `vk_live_` or `vk_test_` and a few characters.",
                          "examples": [
                            "vk_test_8f2k"
                          ]
                        },
                        "last4": {
                          "type": "string",
                          "description": "The last four characters of the secret."
                        },
                        "scopes": {
                          "type": "array",
                          "items": {
                            "type": "string",
                            "enum": [
                              "all",
                              "runtime",
                              "setup",
                              "admin"
                            ]
                          },
                          "description": "What the key may call: `all`, or any of `runtime` (conversations, work, routines, connected apps, files, memory, usage), `setup` (deployments, tests, secrets) and `admin` (users and keys)."
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "active",
                            "expiring",
                            "expired",
                            "revoked"
                          ],
                          "description": "`active`: works, with no end. `expiring`: works until `expires_at` (a rolled key in its grace period, or one made to expire). `expired` or `revoked`: refused."
                        },
                        "created_at": {
                          "type": "string",
                          "description": "When it was made, as an ISO 8601 date and time in UTC."
                        },
                        "last_used_at": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ],
                          "description": "When it last made a call; null when it never has."
                        },
                        "expires_at": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ],
                          "description": "When it stops working; null when it never does."
                        },
                        "revoked_at": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ],
                          "description": "When it was revoked; null while it is not."
                        },
                        "secret": {
                          "type": "string",
                          "description": "The whole key. It is shown this once: store it now, as Vestra keeps only its hash.",
                          "examples": [
                            "vk_test_..."
                          ]
                        }
                      },
                      "required": [
                        "id",
                        "object",
                        "mode",
                        "name",
                        "prefix",
                        "last4",
                        "scopes",
                        "status",
                        "created_at",
                        "last_used_at",
                        "expires_at",
                        "revoked_at",
                        "secret"
                      ],
                      "description": "The new key, with its secret, shown once."
                    },
                    "previous": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "The key's id.",
                          "examples": [
                            "key_8f2k"
                          ]
                        },
                        "object": {
                          "type": "string",
                          "const": "api_key",
                          "description": "Always `api_key`."
                        },
                        "mode": {
                          "type": "string",
                          "enum": [
                            "live",
                            "test"
                          ],
                          "description": "`live` or `test`: what the key reaches. A test key sees only test users, test deployments and test money."
                        },
                        "name": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ],
                          "description": "The name you gave it; null when it has none."
                        },
                        "prefix": {
                          "type": "string",
                          "description": "The start of the secret, to tell keys apart: `vk_live_` or `vk_test_` and a few characters.",
                          "examples": [
                            "vk_test_8f2k"
                          ]
                        },
                        "last4": {
                          "type": "string",
                          "description": "The last four characters of the secret."
                        },
                        "scopes": {
                          "type": "array",
                          "items": {
                            "type": "string",
                            "enum": [
                              "all",
                              "runtime",
                              "setup",
                              "admin"
                            ]
                          },
                          "description": "What the key may call: `all`, or any of `runtime` (conversations, work, routines, connected apps, files, memory, usage), `setup` (deployments, tests, secrets) and `admin` (users and keys)."
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "active",
                            "expiring",
                            "expired",
                            "revoked"
                          ],
                          "description": "`active`: works, with no end. `expiring`: works until `expires_at` (a rolled key in its grace period, or one made to expire). `expired` or `revoked`: refused."
                        },
                        "created_at": {
                          "type": "string",
                          "description": "When it was made, as an ISO 8601 date and time in UTC."
                        },
                        "last_used_at": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ],
                          "description": "When it last made a call; null when it never has."
                        },
                        "expires_at": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ],
                          "description": "When it stops working; null when it never does."
                        },
                        "revoked_at": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ],
                          "description": "When it was revoked; null while it is not."
                        }
                      },
                      "required": [
                        "id",
                        "object",
                        "mode",
                        "name",
                        "prefix",
                        "last4",
                        "scopes",
                        "status",
                        "created_at",
                        "last_used_at",
                        "expires_at",
                        "revoked_at"
                      ],
                      "description": "The old key: it works until its `expires_at`, then stops."
                    }
                  },
                  "required": [
                    "object",
                    "key",
                    "previous"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "grace_seconds": {
                    "default": 86400,
                    "description": "How long the old key keeps working, in seconds, up to 7 days. Default 86400 (a day); 0 stops it at once.",
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 604800
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/keys/{key_id}": {
      "delete": {
        "operationId": "deleteKeysByKeyId",
        "summary": "Revoke a key immediately.",
        "tags": [
          "Account"
        ],
        "x-vestra-line": "keys",
        "x-vestra-scope": "admin",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "key_id",
            "in": "path",
            "required": true,
            "description": "The API key's id (`key_...`).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "The key's id.",
                      "examples": [
                        "key_8f2k"
                      ]
                    },
                    "object": {
                      "type": "string",
                      "const": "api_key",
                      "description": "Always `api_key`."
                    },
                    "mode": {
                      "type": "string",
                      "enum": [
                        "live",
                        "test"
                      ],
                      "description": "`live` or `test`: what the key reaches. A test key sees only test users, test deployments and test money."
                    },
                    "name": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The name you gave it; null when it has none."
                    },
                    "prefix": {
                      "type": "string",
                      "description": "The start of the secret, to tell keys apart: `vk_live_` or `vk_test_` and a few characters.",
                      "examples": [
                        "vk_test_8f2k"
                      ]
                    },
                    "last4": {
                      "type": "string",
                      "description": "The last four characters of the secret."
                    },
                    "scopes": {
                      "type": "array",
                      "items": {
                        "type": "string",
                        "enum": [
                          "all",
                          "runtime",
                          "setup",
                          "admin"
                        ]
                      },
                      "description": "What the key may call: `all`, or any of `runtime` (conversations, work, routines, connected apps, files, memory, usage), `setup` (deployments, tests, secrets) and `admin` (users and keys)."
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "active",
                        "expiring",
                        "expired",
                        "revoked"
                      ],
                      "description": "`active`: works, with no end. `expiring`: works until `expires_at` (a rolled key in its grace period, or one made to expire). `expired` or `revoked`: refused."
                    },
                    "created_at": {
                      "type": "string",
                      "description": "When it was made, as an ISO 8601 date and time in UTC."
                    },
                    "last_used_at": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "When it last made a call; null when it never has."
                    },
                    "expires_at": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "When it stops working; null when it never does."
                    },
                    "revoked_at": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "When it was revoked; null while it is not."
                    }
                  },
                  "required": [
                    "id",
                    "object",
                    "mode",
                    "name",
                    "prefix",
                    "last4",
                    "scopes",
                    "status",
                    "created_at",
                    "last_used_at",
                    "expires_at",
                    "revoked_at"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/limits": {
      "get": {
        "operationId": "getLimits",
        "summary": "The day and month caps for the company and per user, the alert thresholds and the rate limits.",
        "tags": [
          "Account"
        ],
        "x-vestra-line": "usage",
        "x-vestra-scope": "runtime",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "type": "string",
                      "const": "limits",
                      "description": "Always `limits`."
                    },
                    "mode": {
                      "type": "string",
                      "enum": [
                        "live",
                        "test"
                      ],
                      "description": "The mode these limits belong to: the mode of the key in use."
                    },
                    "org_daily_usd": {
                      "anyOf": [
                        {
                          "type": "number",
                          "minimum": 0,
                          "maximum": 1000000
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The company's spending cap per day (UTC), in US dollars, across all its users; null: none, up to the account's ceiling."
                    },
                    "user_daily_usd": {
                      "anyOf": [
                        {
                          "type": "number",
                          "minimum": 0,
                          "maximum": 1000000
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The default cap per user per day (UTC), in US dollars; a user's own `spend_cap_usd` wins. Null: none."
                    },
                    "max_org_daily_usd": {
                      "type": "number",
                      "minimum": 0,
                      "maximum": 1000000,
                      "description": "The highest the company's daily cap may be set, in US dollars. Ask Vestra to raise it."
                    },
                    "org_monthly_usd": {
                      "anyOf": [
                        {
                          "type": "number",
                          "minimum": 0,
                          "maximum": 1000000
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The company's cap per calendar month (UTC), in US dollars. Null (the default): none."
                    },
                    "user_monthly_usd": {
                      "anyOf": [
                        {
                          "type": "number",
                          "minimum": 0,
                          "maximum": 1000000
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The default cap per user per calendar month (UTC), in US dollars; a user's own `monthly_cap_usd` wins. Null (the default): none."
                    },
                    "alert_thresholds": {
                      "maxItems": 5,
                      "type": "array",
                      "items": {
                        "type": "integer",
                        "minimum": 1,
                        "maximum": 100
                      },
                      "description": "Percents of a cap at which usage alerts fire, for the company and each user, per day and per month."
                    },
                    "rate_limits": {
                      "type": "object",
                      "properties": {
                        "requests_per_minute": {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991,
                          "description": "Calls a key may make per minute before 429 `rate_limited`."
                        },
                        "concurrent_task_starts": {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991,
                          "description": "How many computers your company may be waking at once with `warm`; past it, `warm` answers 429 `warm_limit`. Starting work is not limited by this number yet."
                        }
                      },
                      "required": [
                        "requests_per_minute",
                        "concurrent_task_starts"
                      ],
                      "description": "How fast you may call, fixed per account."
                    }
                  },
                  "required": [
                    "object",
                    "mode",
                    "org_daily_usd",
                    "user_daily_usd",
                    "max_org_daily_usd",
                    "org_monthly_usd",
                    "user_monthly_usd",
                    "alert_thresholds",
                    "rate_limits"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "patchLimits",
        "summary": "Set the day and month caps for the company and per user, and the alert thresholds, within what Vestra allows.",
        "tags": [
          "Account"
        ],
        "x-vestra-line": "usage",
        "x-vestra-scope": "admin",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "type": "string",
                      "const": "limits",
                      "description": "Always `limits`."
                    },
                    "mode": {
                      "type": "string",
                      "enum": [
                        "live",
                        "test"
                      ],
                      "description": "The mode these limits belong to: the mode of the key in use."
                    },
                    "org_daily_usd": {
                      "anyOf": [
                        {
                          "type": "number",
                          "minimum": 0,
                          "maximum": 1000000
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The company's spending cap per day (UTC), in US dollars, across all its users; null: none, up to the account's ceiling."
                    },
                    "user_daily_usd": {
                      "anyOf": [
                        {
                          "type": "number",
                          "minimum": 0,
                          "maximum": 1000000
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The default cap per user per day (UTC), in US dollars; a user's own `spend_cap_usd` wins. Null: none."
                    },
                    "max_org_daily_usd": {
                      "type": "number",
                      "minimum": 0,
                      "maximum": 1000000,
                      "description": "The highest the company's daily cap may be set, in US dollars. Ask Vestra to raise it."
                    },
                    "org_monthly_usd": {
                      "anyOf": [
                        {
                          "type": "number",
                          "minimum": 0,
                          "maximum": 1000000
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The company's cap per calendar month (UTC), in US dollars. Null (the default): none."
                    },
                    "user_monthly_usd": {
                      "anyOf": [
                        {
                          "type": "number",
                          "minimum": 0,
                          "maximum": 1000000
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The default cap per user per calendar month (UTC), in US dollars; a user's own `monthly_cap_usd` wins. Null (the default): none."
                    },
                    "alert_thresholds": {
                      "maxItems": 5,
                      "type": "array",
                      "items": {
                        "type": "integer",
                        "minimum": 1,
                        "maximum": 100
                      },
                      "description": "Percents of a cap at which usage alerts fire, for the company and each user, per day and per month."
                    },
                    "rate_limits": {
                      "type": "object",
                      "properties": {
                        "requests_per_minute": {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991,
                          "description": "Calls a key may make per minute before 429 `rate_limited`."
                        },
                        "concurrent_task_starts": {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991,
                          "description": "How many computers your company may be waking at once with `warm`; past it, `warm` answers 429 `warm_limit`. Starting work is not limited by this number yet."
                        }
                      },
                      "required": [
                        "requests_per_minute",
                        "concurrent_task_starts"
                      ],
                      "description": "How fast you may call, fixed per account."
                    }
                  },
                  "required": [
                    "object",
                    "mode",
                    "org_daily_usd",
                    "user_daily_usd",
                    "max_org_daily_usd",
                    "org_monthly_usd",
                    "user_monthly_usd",
                    "alert_thresholds",
                    "rate_limits"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "org_daily_usd": {
                    "description": "The company's cap per day (UTC), in US dollars with at most 2 decimals, up to `max_org_daily_usd`; null removes it.",
                    "anyOf": [
                      {
                        "type": "number",
                        "minimum": 0,
                        "maximum": 1000000
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "user_daily_usd": {
                    "description": "The default cap per user per day (UTC), in US dollars, at most the company cap; null removes it.",
                    "anyOf": [
                      {
                        "type": "number",
                        "minimum": 0,
                        "maximum": 1000000
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "org_monthly_usd": {
                    "description": "The company's cap per calendar month (UTC), in US dollars; null removes it.",
                    "anyOf": [
                      {
                        "type": "number",
                        "minimum": 0,
                        "maximum": 1000000
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "user_monthly_usd": {
                    "description": "The default cap per user per calendar month (UTC), at most the company monthly cap; null removes it.",
                    "anyOf": [
                      {
                        "type": "number",
                        "minimum": 0,
                        "maximum": 1000000
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "alert_thresholds": {
                    "description": "Percents of a cap at which `usage.threshold_reached` fires, whole numbers from 1 to 100, at most four below 100. 100 always fires `usage.cap_reached`.",
                    "examples": [
                      [
                        50,
                        80
                      ]
                    ],
                    "maxItems": 5,
                    "type": "array",
                    "items": {
                      "type": "integer",
                      "minimum": 1,
                      "maximum": 100
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/usage": {
      "get": {
        "operationId": "getUsage",
        "summary": "Exact billed spend and real task counts, by day, user, deployment, conversation, task, model or kind of spend, filtered by user, deployment or conversation. An erased user's spend stays in the totals, as the user unknown.",
        "tags": [
          "Account"
        ],
        "x-vestra-line": "usage",
        "x-vestra-scope": "runtime",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "from",
            "in": "query",
            "required": false,
            "schema": {
              "description": "The first day, inclusive, as YYYY-MM-DD (UTC). Absent: 29 days before `to`.",
              "examples": [
                "2026-09-01"
              ],
              "type": "string",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "schema": {
              "description": "The last day, inclusive, as YYYY-MM-DD (UTC). At most 31 days from `from` to `to`, counting both, so `to` is at most 30 days after `from`. Absent: today.",
              "examples": [
                "2026-09-30"
              ],
              "type": "string",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
            }
          },
          {
            "name": "group_by",
            "in": "query",
            "required": false,
            "schema": {
              "default": "day",
              "description": "How to split the spend: by `day` (the default), `user`, `deployment`, `conversation`, `task`, `model` or `category`.",
              "type": "string",
              "enum": [
                "day",
                "user",
                "deployment",
                "conversation",
                "task",
                "model",
                "category"
              ]
            }
          },
          {
            "name": "user_id",
            "in": "query",
            "required": false,
            "schema": {
              "description": "Only this user's spend, by your own id for them. Absent: every user's, and the company's own Bash's.",
              "type": "string",
              "pattern": "^[A-Za-z0-9][A-Za-z0-9._:@-]{0,127}$",
              "examples": [
                "traveller-42"
              ]
            }
          },
          {
            "name": "deployment_id",
            "in": "query",
            "required": false,
            "schema": {
              "description": "Only this deployment's spend, by its `dep_` id.",
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "conversation_id",
            "in": "query",
            "required": false,
            "schema": {
              "description": "Only this conversation's spend, by its `conv_` id.",
              "type": "string",
              "minLength": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "type": "string",
                      "const": "usage",
                      "description": "Always `usage`."
                    },
                    "mode": {
                      "type": "string",
                      "enum": [
                        "live",
                        "test"
                      ],
                      "description": "The mode this spend is from: the mode of the key in use."
                    },
                    "from": {
                      "type": "string",
                      "description": "The first day counted, as YYYY-MM-DD (UTC)."
                    },
                    "to": {
                      "type": "string",
                      "description": "The last day counted, as YYYY-MM-DD (UTC)."
                    },
                    "group_by": {
                      "type": "string",
                      "enum": [
                        "day",
                        "user",
                        "deployment",
                        "conversation",
                        "task",
                        "model",
                        "category"
                      ],
                      "description": "How the rows are split."
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "key": {
                            "type": "string",
                            "description": "The group, as `group_by` says: the day (`2026-09-30`), your user id, the deployment's, conversation's or task's id, the model, or the category. `none` when the spend belongs to no such thing; `unknown` for spend with no user."
                          },
                          "spend_usd": {
                            "type": "number",
                            "description": "Billed US dollars, exact to 5 decimals. A group whose refunds exceed its charges reads 0."
                          },
                          "tasks": {
                            "type": "integer",
                            "minimum": -9007199254740991,
                            "maximum": 9007199254740991,
                            "description": "The pieces of work that spent in this group. Bash's own replies are not counted as work."
                          }
                        },
                        "required": [
                          "key",
                          "spend_usd",
                          "tasks"
                        ]
                      },
                      "description": "One row per group, with what it spent."
                    },
                    "total": {
                      "type": "object",
                      "properties": {
                        "spend_usd": {
                          "type": "number",
                          "description": "Billed US dollars across every row."
                        },
                        "tasks": {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991,
                          "description": "Pieces of work across every row."
                        }
                      },
                      "required": [
                        "spend_usd",
                        "tasks"
                      ],
                      "description": "The rows added up."
                    }
                  },
                  "required": [
                    "object",
                    "mode",
                    "from",
                    "to",
                    "group_by",
                    "data",
                    "total"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/usage/line-items": {
      "get": {
        "operationId": "getUsageLineItems",
        "summary": "The charges behind one task or one conversation, newest first: the receipt you can show your user.",
        "tags": [
          "Account"
        ],
        "x-vestra-line": "usage",
        "x-vestra-scope": "runtime",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "default": 20,
              "description": "How many items per page, 1 to 100. Default 20.",
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "description": "Where to go on from: the `next_cursor` of the page before, unchanged. Absent: the first page.",
              "type": "string"
            }
          },
          {
            "name": "task_id",
            "in": "query",
            "required": false,
            "schema": {
              "description": "The charges behind this piece of work, by its `task_` id. Send this or `conversation_id`.",
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "conversation_id",
            "in": "query",
            "required": false,
            "schema": {
              "description": "The charges behind this conversation, by its `conv_` id. Send this or `task_id`.",
              "type": "string",
              "minLength": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "The charge's id."
                          },
                          "object": {
                            "type": "string",
                            "const": "usage.line_item",
                            "description": "Always `usage.line_item`."
                          },
                          "category": {
                            "type": "string",
                            "enum": [
                              "orchestrator",
                              "intelligence",
                              "tools",
                              "compute",
                              "background",
                              "voice"
                            ],
                            "description": "The kind of spend: `orchestrator` (Bash's replies), `intelligence` (its thinking at work), `tools`, `compute`, `background` or `voice`."
                          },
                          "amount_usd": {
                            "type": "number",
                            "description": "Billed US dollars; a refund is negative. A subject's items add up to its `cost_usd`."
                          },
                          "model": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "The model the charge was for; null when it was for no model."
                          },
                          "description": {
                            "type": "string",
                            "description": "What the charge was, in a few fixed words such as `Work by Bash`; a refund starts `Refund: `."
                          },
                          "created_at": {
                            "type": "string",
                            "description": "When it was charged, as an ISO 8601 date and time in UTC."
                          }
                        },
                        "required": [
                          "id",
                          "object",
                          "category",
                          "amount_usd",
                          "model",
                          "description",
                          "created_at"
                        ]
                      },
                      "description": "The items on this page."
                    },
                    "next_cursor": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Send it as `cursor` for the next page; null on the last page."
                    }
                  },
                  "required": [
                    "data",
                    "next_cursor"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/audit-log": {
      "get": {
        "operationId": "getAuditLog",
        "summary": "Every key use, settings change and approval answer, newest first.",
        "tags": [
          "Account"
        ],
        "x-vestra-line": "keys",
        "x-vestra-scope": "admin",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "default": 20,
              "description": "How many items per page, 1 to 100. Default 20.",
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "description": "Where to go on from: the `next_cursor` of the page before, unchanged. Absent: the first page.",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "The entry's id."
                          },
                          "object": {
                            "type": "string",
                            "const": "audit_event",
                            "description": "Always `audit_event`."
                          },
                          "mode": {
                            "anyOf": [
                              {
                                "type": "string",
                                "enum": [
                                  "live",
                                  "test"
                                ],
                                "description": "`live` or `test`. A test key sees only test users, test deployments and test money."
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "The mode it happened in; null for a Vestra staff action on the company account."
                          },
                          "action": {
                            "type": "string",
                            "description": "What was done, such as `task.deleted` or `notebook.created`.",
                            "examples": [
                              "task.deleted"
                            ]
                          },
                          "actor": {
                            "type": "object",
                            "properties": {
                              "kind": {
                                "type": "string",
                                "description": "Who did it: `key` (an API key), `console` (a person signed in), `client` (a session token) or `staff` (Vestra)."
                              },
                              "id": {
                                "anyOf": [
                                  {
                                    "type": "string"
                                  },
                                  {
                                    "type": "null"
                                  }
                                ],
                                "description": "The key's id, the signed-in person's, or the session's; null when there is none to show."
                              }
                            },
                            "required": [
                              "kind",
                              "id"
                            ],
                            "description": "Who did it."
                          },
                          "target": {
                            "type": "object",
                            "properties": {
                              "type": {
                                "type": "string",
                                "description": "What kind of thing it was done to, such as `task`, `notebook` or `interaction`."
                              },
                              "id": {
                                "type": "string",
                                "description": "Its id."
                              }
                            },
                            "required": [
                              "type",
                              "id"
                            ],
                            "description": "What it was done to."
                          },
                          "detail": {
                            "anyOf": [
                              {
                                "type": "object",
                                "propertyNames": {
                                  "type": "string"
                                },
                                "additionalProperties": {}
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "More about it, such as the fields that changed. It never holds a secret or a key; null when there is nothing more."
                          },
                          "created_at": {
                            "type": "string",
                            "description": "When it happened, as an ISO 8601 date and time in UTC."
                          }
                        },
                        "required": [
                          "id",
                          "object",
                          "mode",
                          "action",
                          "actor",
                          "target",
                          "detail",
                          "created_at"
                        ]
                      },
                      "description": "The items on this page."
                    },
                    "next_cursor": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Send it as `cursor` for the next page; null on the last page."
                    }
                  },
                  "required": [
                    "data",
                    "next_cursor"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/models": {
      "get": {
        "operationId": "getModels",
        "summary": "The models a deployment may choose from.",
        "tags": [
          "Account"
        ],
        "x-vestra-line": "keys",
        "x-vestra-scope": "runtime",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "The model's id: what a deployment's `model` takes."
                          },
                          "object": {
                            "type": "string",
                            "const": "model",
                            "description": "Always `model`."
                          },
                          "label": {
                            "type": "string",
                            "description": "Its name, as a person reads it."
                          }
                        },
                        "required": [
                          "id",
                          "object",
                          "label"
                        ]
                      },
                      "description": "The items on this page."
                    },
                    "next_cursor": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Send it as `cursor` for the next page; null on the last page."
                    }
                  },
                  "required": [
                    "data",
                    "next_cursor"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/health": {
      "get": {
        "operationId": "getHealth",
        "summary": "Is the API up. No key needed.",
        "tags": [
          "Account"
        ],
        "x-vestra-line": "keys",
        "security": [],
        "parameters": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "type": "string",
                      "const": "health",
                      "description": "Always `health`."
                    },
                    "ok": {
                      "type": "boolean",
                      "const": true,
                      "description": "Always true: the API is up and answering."
                    },
                    "time": {
                      "type": "string",
                      "description": "The server's time, as an ISO 8601 date and time in UTC.",
                      "examples": [
                        "2026-10-02T08:30:00.000Z"
                      ]
                    }
                  },
                  "required": [
                    "object",
                    "ok",
                    "time"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/users": {
      "post": {
        "operationId": "postUsers",
        "summary": "Create one of your users, or return the existing one. Safe to repeat with the same user_id.",
        "tags": [
          "Users"
        ],
        "x-vestra-line": "users",
        "x-vestra-scope": "admin",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 255
            },
            "description": "Send the same key to retry this call safely for 24 hours."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "Your own id for the user.",
                      "examples": [
                        "traveller-42"
                      ]
                    },
                    "object": {
                      "type": "string",
                      "const": "user",
                      "description": "Always user."
                    },
                    "name": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The user's name; null when you gave none."
                    },
                    "email": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The user's email address; null when you gave none."
                    },
                    "locale": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The user's language and region (BCP 47); null when you gave none."
                    },
                    "timezone": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The user's time zone (IANA); null when you gave none, and their routines then run in UTC."
                    },
                    "metadata": {
                      "type": "object",
                      "propertyNames": {
                        "type": "string"
                      },
                      "additionalProperties": {},
                      "description": "Your own facts about the user; empty when you gave none."
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "active",
                        "disabled"
                      ],
                      "description": "active, or disabled: a disabled user's calls are refused (403 user_disabled) until you turn them back on."
                    },
                    "spend_cap_usd": {
                      "anyOf": [
                        {
                          "type": "number"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The user's own cap per day, in billed US dollars, never above your company's; null: your company's cap for each user, if any."
                    },
                    "monthly_cap_usd": {
                      "anyOf": [
                        {
                          "type": "number"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The user's own cap per calendar month (UTC), in billed US dollars; null: your company's cap for each user, if any."
                    },
                    "default_deployment": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The deployment their conversations use when none is named (dep_...); null: your company's default."
                    },
                    "memory_mode": {
                      "type": "string",
                      "enum": [
                        "vestra",
                        "customer",
                        "none"
                      ],
                      "description": "Where Bash's memory of this user lives: `vestra`, `customer` (your memory endpoint), or `none`."
                    },
                    "is_service_user": {
                      "type": "boolean",
                      "description": "true for a user Vestra keeps for itself, such as your company's own Bash; false for your users."
                    },
                    "created_at": {
                      "type": "string",
                      "description": "When the user was made, as an ISO 8601 time."
                    },
                    "spend_today_usd": {
                      "type": "number",
                      "description": "What they have spent today (UTC), in billed US dollars.",
                      "examples": [
                        1.24
                      ]
                    },
                    "spend_month_usd": {
                      "type": "number",
                      "description": "What they have spent this calendar month (UTC), in billed US dollars.",
                      "examples": [
                        18.6
                      ]
                    },
                    "caps_remaining": {
                      "type": "object",
                      "properties": {
                        "day_usd": {
                          "anyOf": [
                            {
                              "type": "number"
                            },
                            {
                              "type": "null"
                            }
                          ],
                          "description": "What they may still spend today, in US dollars; null when no cap applies."
                        },
                        "month_usd": {
                          "anyOf": [
                            {
                              "type": "number"
                            },
                            {
                              "type": "null"
                            }
                          ],
                          "description": "What they may still spend this month, in US dollars; null when no cap applies."
                        }
                      },
                      "required": [
                        "day_usd",
                        "month_usd"
                      ],
                      "description": "What is left under every cap that applies to them: the smaller of their own and your company's."
                    }
                  },
                  "required": [
                    "id",
                    "object",
                    "name",
                    "email",
                    "locale",
                    "timezone",
                    "metadata",
                    "status",
                    "spend_cap_usd",
                    "monthly_cap_usd",
                    "default_deployment",
                    "memory_mode",
                    "is_service_user",
                    "created_at",
                    "spend_today_usd",
                    "spend_month_usd",
                    "caps_remaining"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "user_id": {
                    "type": "string",
                    "pattern": "^[A-Za-z0-9][A-Za-z0-9._:@-]{0,127}$",
                    "description": "Your own id for the user. Sending one that exists changes nothing and makes no second user.",
                    "examples": [
                      "traveller-42"
                    ]
                  },
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 200,
                    "description": "The user's name, as Bash may call them: at most 200 characters.",
                    "examples": [
                      "Priya Sharma"
                    ]
                  },
                  "email": {
                    "type": "string",
                    "maxLength": 320,
                    "format": "email",
                    "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$",
                    "description": "The user's email address.",
                    "examples": [
                      "priya@example.com"
                    ]
                  },
                  "locale": {
                    "type": "string",
                    "minLength": 2,
                    "maxLength": 35,
                    "description": "The user's language and region, as a BCP 47 tag.",
                    "examples": [
                      "en-IN"
                    ]
                  },
                  "timezone": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 64,
                    "description": "The user's time zone, as an IANA name: their routines run in it.",
                    "examples": [
                      "Asia/Kolkata"
                    ]
                  },
                  "metadata": {
                    "description": "Your own facts about the user, as JSON, given back as you sent them.",
                    "type": "object",
                    "propertyNames": {
                      "type": "string"
                    },
                    "additionalProperties": {}
                  }
                },
                "required": [
                  "user_id"
                ]
              }
            }
          }
        }
      },
      "get": {
        "operationId": "getUsers",
        "summary": "List your users.",
        "tags": [
          "Users"
        ],
        "x-vestra-line": "users",
        "x-vestra-scope": "runtime",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "default": 20,
              "description": "How many items per page, 1 to 100. Default 20.",
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "description": "Where to go on from: the `next_cursor` of the page before, unchanged. Absent: the first page.",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "Your own id for the user.",
                            "examples": [
                              "traveller-42"
                            ]
                          },
                          "object": {
                            "type": "string",
                            "const": "user",
                            "description": "Always user."
                          },
                          "name": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "The user's name; null when you gave none."
                          },
                          "email": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "The user's email address; null when you gave none."
                          },
                          "locale": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "The user's language and region (BCP 47); null when you gave none."
                          },
                          "timezone": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "The user's time zone (IANA); null when you gave none, and their routines then run in UTC."
                          },
                          "metadata": {
                            "type": "object",
                            "propertyNames": {
                              "type": "string"
                            },
                            "additionalProperties": {},
                            "description": "Your own facts about the user; empty when you gave none."
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "active",
                              "disabled"
                            ],
                            "description": "active, or disabled: a disabled user's calls are refused (403 user_disabled) until you turn them back on."
                          },
                          "spend_cap_usd": {
                            "anyOf": [
                              {
                                "type": "number"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "The user's own cap per day, in billed US dollars, never above your company's; null: your company's cap for each user, if any."
                          },
                          "monthly_cap_usd": {
                            "anyOf": [
                              {
                                "type": "number"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "The user's own cap per calendar month (UTC), in billed US dollars; null: your company's cap for each user, if any."
                          },
                          "default_deployment": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "The deployment their conversations use when none is named (dep_...); null: your company's default."
                          },
                          "memory_mode": {
                            "type": "string",
                            "enum": [
                              "vestra",
                              "customer",
                              "none"
                            ],
                            "description": "Where Bash's memory of this user lives: `vestra`, `customer` (your memory endpoint), or `none`."
                          },
                          "is_service_user": {
                            "type": "boolean",
                            "description": "true for a user Vestra keeps for itself, such as your company's own Bash; false for your users."
                          },
                          "created_at": {
                            "type": "string",
                            "description": "When the user was made, as an ISO 8601 time."
                          }
                        },
                        "required": [
                          "id",
                          "object",
                          "name",
                          "email",
                          "locale",
                          "timezone",
                          "metadata",
                          "status",
                          "spend_cap_usd",
                          "monthly_cap_usd",
                          "default_deployment",
                          "memory_mode",
                          "is_service_user",
                          "created_at"
                        ]
                      },
                      "description": "The items on this page."
                    },
                    "next_cursor": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Send it as `cursor` for the next page; null on the last page."
                    }
                  },
                  "required": [
                    "data",
                    "next_cursor"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/users/{user_id}": {
      "get": {
        "operationId": "getUsersByUserId",
        "summary": "One user: status, profile, memory mode, default deployment, and what they spent today and this month against their caps.",
        "tags": [
          "Users"
        ],
        "x-vestra-line": "users",
        "x-vestra-scope": "runtime",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "user_id",
            "in": "path",
            "required": true,
            "description": "Your own id for the user, as you named them.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "Your own id for the user.",
                      "examples": [
                        "traveller-42"
                      ]
                    },
                    "object": {
                      "type": "string",
                      "const": "user",
                      "description": "Always user."
                    },
                    "name": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The user's name; null when you gave none."
                    },
                    "email": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The user's email address; null when you gave none."
                    },
                    "locale": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The user's language and region (BCP 47); null when you gave none."
                    },
                    "timezone": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The user's time zone (IANA); null when you gave none, and their routines then run in UTC."
                    },
                    "metadata": {
                      "type": "object",
                      "propertyNames": {
                        "type": "string"
                      },
                      "additionalProperties": {},
                      "description": "Your own facts about the user; empty when you gave none."
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "active",
                        "disabled"
                      ],
                      "description": "active, or disabled: a disabled user's calls are refused (403 user_disabled) until you turn them back on."
                    },
                    "spend_cap_usd": {
                      "anyOf": [
                        {
                          "type": "number"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The user's own cap per day, in billed US dollars, never above your company's; null: your company's cap for each user, if any."
                    },
                    "monthly_cap_usd": {
                      "anyOf": [
                        {
                          "type": "number"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The user's own cap per calendar month (UTC), in billed US dollars; null: your company's cap for each user, if any."
                    },
                    "default_deployment": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The deployment their conversations use when none is named (dep_...); null: your company's default."
                    },
                    "memory_mode": {
                      "type": "string",
                      "enum": [
                        "vestra",
                        "customer",
                        "none"
                      ],
                      "description": "Where Bash's memory of this user lives: `vestra`, `customer` (your memory endpoint), or `none`."
                    },
                    "is_service_user": {
                      "type": "boolean",
                      "description": "true for a user Vestra keeps for itself, such as your company's own Bash; false for your users."
                    },
                    "created_at": {
                      "type": "string",
                      "description": "When the user was made, as an ISO 8601 time."
                    },
                    "spend_today_usd": {
                      "type": "number",
                      "description": "What they have spent today (UTC), in billed US dollars.",
                      "examples": [
                        1.24
                      ]
                    },
                    "spend_month_usd": {
                      "type": "number",
                      "description": "What they have spent this calendar month (UTC), in billed US dollars.",
                      "examples": [
                        18.6
                      ]
                    },
                    "caps_remaining": {
                      "type": "object",
                      "properties": {
                        "day_usd": {
                          "anyOf": [
                            {
                              "type": "number"
                            },
                            {
                              "type": "null"
                            }
                          ],
                          "description": "What they may still spend today, in US dollars; null when no cap applies."
                        },
                        "month_usd": {
                          "anyOf": [
                            {
                              "type": "number"
                            },
                            {
                              "type": "null"
                            }
                          ],
                          "description": "What they may still spend this month, in US dollars; null when no cap applies."
                        }
                      },
                      "required": [
                        "day_usd",
                        "month_usd"
                      ],
                      "description": "What is left under every cap that applies to them: the smaller of their own and your company's."
                    }
                  },
                  "required": [
                    "id",
                    "object",
                    "name",
                    "email",
                    "locale",
                    "timezone",
                    "metadata",
                    "status",
                    "spend_cap_usd",
                    "monthly_cap_usd",
                    "default_deployment",
                    "memory_mode",
                    "is_service_user",
                    "created_at",
                    "spend_today_usd",
                    "spend_month_usd",
                    "caps_remaining"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "patchUsersByUserId",
        "summary": "Change name, language, time zone, metadata, day or month spend cap, default deployment, or status (active or disabled).",
        "tags": [
          "Users"
        ],
        "x-vestra-line": "users",
        "x-vestra-scope": "admin",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "user_id",
            "in": "path",
            "required": true,
            "description": "Your own id for the user, as you named them.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "Your own id for the user.",
                      "examples": [
                        "traveller-42"
                      ]
                    },
                    "object": {
                      "type": "string",
                      "const": "user",
                      "description": "Always user."
                    },
                    "name": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The user's name; null when you gave none."
                    },
                    "email": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The user's email address; null when you gave none."
                    },
                    "locale": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The user's language and region (BCP 47); null when you gave none."
                    },
                    "timezone": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The user's time zone (IANA); null when you gave none, and their routines then run in UTC."
                    },
                    "metadata": {
                      "type": "object",
                      "propertyNames": {
                        "type": "string"
                      },
                      "additionalProperties": {},
                      "description": "Your own facts about the user; empty when you gave none."
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "active",
                        "disabled"
                      ],
                      "description": "active, or disabled: a disabled user's calls are refused (403 user_disabled) until you turn them back on."
                    },
                    "spend_cap_usd": {
                      "anyOf": [
                        {
                          "type": "number"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The user's own cap per day, in billed US dollars, never above your company's; null: your company's cap for each user, if any."
                    },
                    "monthly_cap_usd": {
                      "anyOf": [
                        {
                          "type": "number"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The user's own cap per calendar month (UTC), in billed US dollars; null: your company's cap for each user, if any."
                    },
                    "default_deployment": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The deployment their conversations use when none is named (dep_...); null: your company's default."
                    },
                    "memory_mode": {
                      "type": "string",
                      "enum": [
                        "vestra",
                        "customer",
                        "none"
                      ],
                      "description": "Where Bash's memory of this user lives: `vestra`, `customer` (your memory endpoint), or `none`."
                    },
                    "is_service_user": {
                      "type": "boolean",
                      "description": "true for a user Vestra keeps for itself, such as your company's own Bash; false for your users."
                    },
                    "created_at": {
                      "type": "string",
                      "description": "When the user was made, as an ISO 8601 time."
                    },
                    "spend_today_usd": {
                      "type": "number",
                      "description": "What they have spent today (UTC), in billed US dollars.",
                      "examples": [
                        1.24
                      ]
                    },
                    "spend_month_usd": {
                      "type": "number",
                      "description": "What they have spent this calendar month (UTC), in billed US dollars.",
                      "examples": [
                        18.6
                      ]
                    },
                    "caps_remaining": {
                      "type": "object",
                      "properties": {
                        "day_usd": {
                          "anyOf": [
                            {
                              "type": "number"
                            },
                            {
                              "type": "null"
                            }
                          ],
                          "description": "What they may still spend today, in US dollars; null when no cap applies."
                        },
                        "month_usd": {
                          "anyOf": [
                            {
                              "type": "number"
                            },
                            {
                              "type": "null"
                            }
                          ],
                          "description": "What they may still spend this month, in US dollars; null when no cap applies."
                        }
                      },
                      "required": [
                        "day_usd",
                        "month_usd"
                      ],
                      "description": "What is left under every cap that applies to them: the smaller of their own and your company's."
                    }
                  },
                  "required": [
                    "id",
                    "object",
                    "name",
                    "email",
                    "locale",
                    "timezone",
                    "metadata",
                    "status",
                    "spend_cap_usd",
                    "monthly_cap_usd",
                    "default_deployment",
                    "memory_mode",
                    "is_service_user",
                    "created_at",
                    "spend_today_usd",
                    "spend_month_usd",
                    "caps_remaining"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "description": "A new name; null clears it.",
                    "anyOf": [
                      {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 200,
                        "description": "The user's name, as Bash may call them: at most 200 characters.",
                        "examples": [
                          "Priya Sharma"
                        ]
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "email": {
                    "description": "A new email address; null clears it.",
                    "anyOf": [
                      {
                        "type": "string",
                        "maxLength": 320,
                        "format": "email",
                        "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$",
                        "description": "The user's email address.",
                        "examples": [
                          "priya@example.com"
                        ]
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "locale": {
                    "description": "A new language and region (BCP 47); null clears it.",
                    "anyOf": [
                      {
                        "type": "string",
                        "minLength": 2,
                        "maxLength": 35,
                        "description": "The user's language and region, as a BCP 47 tag.",
                        "examples": [
                          "en-IN"
                        ]
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "timezone": {
                    "description": "A new time zone (IANA); null clears it, and their routines then run in UTC.",
                    "anyOf": [
                      {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 64,
                        "description": "The user's time zone, as an IANA name: their routines run in it.",
                        "examples": [
                          "Asia/Kolkata"
                        ]
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "metadata": {
                    "description": "Your facts about the user: this takes the place of what was there.",
                    "type": "object",
                    "propertyNames": {
                      "type": "string"
                    },
                    "additionalProperties": {}
                  },
                  "spend_cap_usd": {
                    "description": "Their own cap per day, in US dollars, never above your company's; null goes back to your company's cap for each user.",
                    "anyOf": [
                      {
                        "type": "number",
                        "minimum": 0,
                        "maximum": 1000000
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "monthly_cap_usd": {
                    "description": "Their own cap per calendar month, in US dollars; null goes back to your company's cap for each user.",
                    "anyOf": [
                      {
                        "type": "number",
                        "minimum": 0,
                        "maximum": 1000000
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "default_deployment": {
                    "description": "The deployment their conversations use when none is named: its id or name; null goes back to your company's default.",
                    "anyOf": [
                      {
                        "type": "string",
                        "minLength": 1
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "status": {
                    "description": "disabled refuses their calls (403 user_disabled) until you set active again.",
                    "type": "string",
                    "enum": [
                      "active",
                      "disabled"
                    ]
                  }
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteUsersByUserId",
        "summary": "Erase the user and everything Bash holds for them: computer, files, memory. Runs as a job; a webhook says when it is done.",
        "tags": [
          "Users"
        ],
        "x-vestra-line": "users",
        "x-vestra-scope": "admin",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "user_id",
            "in": "path",
            "required": true,
            "description": "Your own id for the user, as you named them.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "202": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "Your own id for the user."
                    },
                    "object": {
                      "type": "string",
                      "const": "user",
                      "description": "Always user."
                    },
                    "deleted": {
                      "type": "boolean",
                      "const": false,
                      "description": "Always false here: erasing runs in the background, and user.deleted says when it is done."
                    },
                    "status": {
                      "type": "string",
                      "const": "deleting",
                      "description": "Always deleting."
                    }
                  },
                  "required": [
                    "id",
                    "object",
                    "deleted",
                    "status"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/users/{user_id}/export": {
      "post": {
        "operationId": "postUsersByUserIdExport",
        "summary": "Package everything held for the user into one download, for data-rights requests.",
        "tags": [
          "Users"
        ],
        "x-vestra-line": "users",
        "x-vestra-scope": "admin",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "user_id",
            "in": "path",
            "required": true,
            "description": "Your own id for the user, as you named them.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "type": "string",
                      "const": "user_export",
                      "description": "Always user_export."
                    },
                    "url": {
                      "type": "string",
                      "description": "A link to everything Vestra holds for the user, as one JSON file: good for 15 minutes."
                    },
                    "expires_at": {
                      "type": "string",
                      "description": "When the link stops working, as an ISO 8601 time."
                    },
                    "bytes": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991,
                      "description": "The size of the file, in bytes."
                    },
                    "truncated": {
                      "type": "boolean",
                      "description": "true when the user has more than the 200 tasks it holds: the oldest are left out."
                    }
                  },
                  "required": [
                    "object",
                    "url",
                    "expires_at",
                    "bytes",
                    "truncated"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/conversations": {
      "post": {
        "operationId": "postConversations",
        "summary": "Ask. Start a conversation, optionally with its first message and that message's options (context, attachments, output_schema, success_criteria, tools, hand_off). user_id names whose Bash it is, created on first use; leave it out for the company's own Bash. stream: true answers the first turn's events as text/event-stream and ends when the turn settles.",
        "tags": [
          "Conversations"
        ],
        "x-vestra-line": "ask",
        "x-vestra-scope": "runtime",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 255
            },
            "description": "Send the same key to retry this call safely for 24 hours."
          }
        ],
        "responses": {
          "201": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "The conversation (conv_...).",
                      "examples": [
                        "conv_8f2k"
                      ]
                    },
                    "object": {
                      "type": "string",
                      "const": "conversation",
                      "description": "Always conversation."
                    },
                    "user_id": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Your id for the user; null on your company's own Bash, and on an agent's conversation over A2A that names no user."
                    },
                    "deployment_id": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The deployment that answers it (dep_...); null when it has none."
                    },
                    "deployment_version": {
                      "anyOf": [
                        {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The version of the deployment it runs on: in test mode the one it started on, in live mode the one live at its last message. Null with no deployment."
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "idle",
                        "replying",
                        "working",
                        "waiting"
                      ],
                      "description": "What the conversation is doing. idle: nothing. replying: Bash is writing its reply. working: work Bash started is running. waiting: Bash waits on an approval, a question or a call to one of your tools."
                    },
                    "metadata": {
                      "type": "object",
                      "propertyNames": {
                        "type": "string"
                      },
                      "additionalProperties": {
                        "type": "string"
                      },
                      "description": "Your labels, as you sent them; empty when you sent none."
                    },
                    "created_at": {
                      "type": "string",
                      "description": "When it started, as an ISO 8601 time."
                    },
                    "last_active_at": {
                      "type": "string",
                      "description": "When a message or its work last changed it, as an ISO 8601 time."
                    },
                    "open_work": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "task_id": {
                            "type": "string",
                            "description": "The task (task_...)."
                          },
                          "title": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "What the work is, in a few words; null until Bash names it."
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "queued",
                              "working",
                              "waiting",
                              "done",
                              "failed"
                            ],
                            "description": "Where a piece of work is. queued: not started yet. working: running on the user's computer. waiting: it waits on an approval or a question. done or failed: it has ended."
                          }
                        },
                        "required": [
                          "task_id",
                          "title",
                          "status"
                        ]
                      },
                      "description": "Work Bash started that has not ended, oldest first."
                    },
                    "open_interactions": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "interaction_id": {
                            "type": "string",
                            "description": "The approval or question, to answer by its id (int_...)."
                          },
                          "task_id": {
                            "type": "string",
                            "description": "The task that asked (task_...)."
                          },
                          "kind": {
                            "type": "string",
                            "description": "What it asks for, as stored: such as tool_permission, ask_question or composio_auth."
                          }
                        },
                        "required": [
                          "interaction_id",
                          "task_id",
                          "kind"
                        ]
                      },
                      "description": "Approvals and questions Bash waits on."
                    },
                    "pending_tool_calls": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "call_id": {
                            "type": "string",
                            "description": "The call, to answer by its id (call_...)."
                          },
                          "name": {
                            "type": "string",
                            "description": "The tool Bash called."
                          },
                          "arguments": {
                            "description": "What Bash passed, matching the input schema of the tool."
                          },
                          "task_id": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "The task that made the call; null when Bash's reply made it."
                          }
                        },
                        "required": [
                          "call_id",
                          "name",
                          "arguments",
                          "task_id"
                        ]
                      },
                      "description": "Calls to your tools that wait on your answer."
                    },
                    "last_event_seq": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991,
                      "description": "The seq of the newest event on its stream: read the conversation, then follow its events after this seq, and you miss nothing."
                    },
                    "cost_usd": {
                      "type": "number",
                      "description": "What it has cost so far, in billed US dollars: Bash's replies, all its work and its voice calls.",
                      "examples": [
                        0.0412
                      ]
                    },
                    "cost_breakdown": {
                      "type": "object",
                      "properties": {
                        "orchestrator": {
                          "type": "number",
                          "description": "Bash's own replies in the conversation, in billed US dollars; 0 on a piece of work."
                        },
                        "intelligence": {
                          "type": "number",
                          "description": "The thinking Bash did while it worked, in billed US dollars."
                        },
                        "tools": {
                          "type": "number",
                          "description": "The tools and apps Bash used, in billed US dollars."
                        },
                        "compute": {
                          "type": "number",
                          "description": "Time on Bash's computer, in billed US dollars."
                        },
                        "background": {
                          "type": "number",
                          "description": "Work Bash did in the background, such as remembering and tidying, in billed US dollars."
                        },
                        "voice": {
                          "type": "number",
                          "description": "Voice call time, in billed US dollars."
                        }
                      },
                      "required": [
                        "orchestrator",
                        "intelligence",
                        "tools",
                        "compute",
                        "background",
                        "voice"
                      ],
                      "description": "The same cost, by kind of spend."
                    },
                    "turn_id": {
                      "description": "The turn of the first message, when you sent one (turn_...).",
                      "type": "string"
                    }
                  },
                  "required": [
                    "id",
                    "object",
                    "user_id",
                    "deployment_id",
                    "deployment_version",
                    "status",
                    "metadata",
                    "created_at",
                    "last_active_at",
                    "open_work",
                    "open_interactions",
                    "pending_tool_calls",
                    "last_event_seq",
                    "cost_usd",
                    "cost_breakdown"
                  ]
                }
              },
              "text/event-stream": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "user_id": {
                    "description": "Your id for the user this conversation is for; Vestra makes the user the first time you name them. Absent: your company's own Bash.",
                    "examples": [
                      "traveller-42"
                    ],
                    "type": "string",
                    "pattern": "^[A-Za-z0-9][A-Za-z0-9._:@-]{0,127}$"
                  },
                  "deployment": {
                    "description": "Which deployment answers: its id (dep_...) or its name. Absent: the user's default deployment, then your company's.",
                    "examples": [
                      "travel-help"
                    ],
                    "type": "string",
                    "minLength": 1
                  },
                  "metadata": {
                    "type": "object",
                    "propertyNames": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 64
                    },
                    "additionalProperties": {
                      "type": "string",
                      "maxLength": 512
                    },
                    "description": "Your own labels, given back as you sent them: at most 32 keys of 1 to 64 characters, each value a string of at most 512. Bash never reads them.",
                    "examples": [
                      {
                        "order_id": "ORD-1042",
                        "channel": "app"
                      }
                    ]
                  },
                  "message": {
                    "description": "A first message, in at most 32,000 characters. Absent, with no attachment: the conversation starts empty.",
                    "examples": [
                      "When does my flight on TN-48213 leave?"
                    ],
                    "type": "string",
                    "maxLength": 32000
                  },
                  "context": {
                    "description": "Facts for this message only, as JSON. Bash reads them as data, never as instructions.",
                    "examples": [
                      {
                        "booking_reference": "TN-48213",
                        "tier": "gold"
                      }
                    ],
                    "type": "object",
                    "propertyNames": {
                      "type": "string"
                    },
                    "additionalProperties": {}
                  },
                  "attachments": {
                    "description": "Files Bash should read with this message: at most 10.",
                    "maxItems": 10,
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "file_id": {
                          "type": "string",
                          "minLength": 1,
                          "description": "A file you uploaded with POST /v1/files (file_...)."
                        }
                      },
                      "required": [
                        "file_id"
                      ]
                    }
                  },
                  "output_schema": {
                    "description": "A JSON Schema, at most 32 KB, for the data you want back: the turn's data matches it.",
                    "examples": [
                      {
                        "type": "object",
                        "properties": {
                          "flight": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "flight"
                        ]
                      }
                    ],
                    "type": "object",
                    "propertyNames": {
                      "type": "string"
                    },
                    "additionalProperties": {}
                  },
                  "success_criteria": {
                    "description": "What a good result looks like, in your words: when the turn settles, its outcome says whether it was met, and why.",
                    "examples": [
                      "A new booking on a flight that leaves before noon."
                    ],
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 4000
                  },
                  "tools": {
                    "description": "Tools your code answers, for this message only, on top of the deployment's: at most 32.",
                    "maxItems": 32,
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "name": {
                          "type": "string",
                          "pattern": "^(?!mcp__)[a-z][a-z0-9_]{0,63}$",
                          "description": "The tool's name: lowercase letters, digits and underscores, starting with a letter, up to 64.",
                          "examples": [
                            "get_booking"
                          ]
                        },
                        "description": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 1024,
                          "description": "What the tool does, so Bash knows when to call it, up to 1024 characters.",
                          "examples": [
                            "A booking by its PNR"
                          ]
                        },
                        "input_schema": {
                          "type": "object",
                          "propertyNames": {
                            "type": "string"
                          },
                          "additionalProperties": {},
                          "description": "Its arguments, as JSON Schema with `type: object`. Bash's call fills them in.",
                          "examples": [
                            {
                              "type": "object",
                              "properties": {
                                "pnr": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "pnr"
                              ]
                            }
                          ]
                        },
                        "timeout_s": {
                          "default": 120,
                          "description": "Seconds Bash waits for your answer, 5 to 600. Default 120; after it, the call expires.",
                          "type": "integer",
                          "minimum": 5,
                          "maximum": 600
                        },
                        "read_only": {
                          "description": "true: the tool changes nothing (a lookup), so Bash calls it without waiting for the person's yes. Absent: false.",
                          "type": "boolean"
                        },
                        "run_without_asking": {
                          "description": "true: the tool changes something that needs no yes, so Bash calls it without waiting for the person's yes. Absent: false.",
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "name",
                        "description",
                        "input_schema"
                      ]
                    }
                  },
                  "hand_off": {
                    "description": "For the first message: auto lets Bash reply first; always sends it straight to work. Default: auto.",
                    "type": "string",
                    "enum": [
                      "auto",
                      "always"
                    ]
                  },
                  "stream": {
                    "description": "true answers with the turn's events as they happen (text/event-stream), ending when the turn settles. Default: one JSON answer.",
                    "type": "boolean"
                  }
                },
                "additionalProperties": false
              }
            }
          }
        }
      },
      "get": {
        "operationId": "getConversations",
        "summary": "Conversations, newest first: one user's with user_id, or every one of the company's without it (the company's own Bash shows user_id null).",
        "tags": [
          "Conversations"
        ],
        "x-vestra-line": "ask",
        "x-vestra-scope": "runtime",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "default": 20,
              "description": "How many items per page, 1 to 100. Default 20.",
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "description": "Where to go on from: the `next_cursor` of the page before, unchanged. Absent: the first page.",
              "type": "string"
            }
          },
          {
            "name": "user_id",
            "in": "query",
            "required": false,
            "schema": {
              "description": "Only this user's conversations, by your id for them. Absent: every conversation of your company.",
              "type": "string",
              "pattern": "^[A-Za-z0-9][A-Za-z0-9._:@-]{0,127}$",
              "examples": [
                "traveller-42"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "The conversation (conv_...).",
                            "examples": [
                              "conv_8f2k"
                            ]
                          },
                          "object": {
                            "type": "string",
                            "const": "conversation",
                            "description": "Always conversation."
                          },
                          "user_id": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "Your id for the user; null on your company's own Bash, and on an agent's conversation over A2A that names no user."
                          },
                          "deployment_id": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "The deployment that answers it (dep_...); null when it has none."
                          },
                          "deployment_version": {
                            "anyOf": [
                              {
                                "type": "integer",
                                "minimum": -9007199254740991,
                                "maximum": 9007199254740991
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "The version of the deployment it runs on: in test mode the one it started on, in live mode the one live at its last message. Null with no deployment."
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "idle",
                              "replying",
                              "working",
                              "waiting"
                            ],
                            "description": "What the conversation is doing. idle: nothing. replying: Bash is writing its reply. working: work Bash started is running. waiting: Bash waits on an approval, a question or a call to one of your tools."
                          },
                          "metadata": {
                            "type": "object",
                            "propertyNames": {
                              "type": "string"
                            },
                            "additionalProperties": {
                              "type": "string"
                            },
                            "description": "Your labels, as you sent them; empty when you sent none."
                          },
                          "created_at": {
                            "type": "string",
                            "description": "When it started, as an ISO 8601 time."
                          },
                          "last_active_at": {
                            "type": "string",
                            "description": "When a message or its work last changed it, as an ISO 8601 time."
                          }
                        },
                        "required": [
                          "id",
                          "object",
                          "user_id",
                          "deployment_id",
                          "deployment_version",
                          "status",
                          "metadata",
                          "created_at",
                          "last_active_at"
                        ]
                      },
                      "description": "The items on this page."
                    },
                    "next_cursor": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Send it as `cursor` for the next page; null on the last page."
                    }
                  },
                  "required": [
                    "data",
                    "next_cursor"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/conversations/{conversation_id}": {
      "get": {
        "operationId": "getConversationsByConversationId",
        "summary": "One conversation: status (idle, replying, working, waiting), its open work, its open approvals.",
        "tags": [
          "Conversations"
        ],
        "x-vestra-line": "ask",
        "x-vestra-scope": "runtime",
        "security": [
          {
            "apiKey": []
          },
          {
            "clientToken": []
          }
        ],
        "parameters": [
          {
            "name": "conversation_id",
            "in": "path",
            "required": true,
            "description": "The conversation's id (`conv_...`).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "The conversation (conv_...).",
                      "examples": [
                        "conv_8f2k"
                      ]
                    },
                    "object": {
                      "type": "string",
                      "const": "conversation",
                      "description": "Always conversation."
                    },
                    "user_id": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Your id for the user; null on your company's own Bash, and on an agent's conversation over A2A that names no user."
                    },
                    "deployment_id": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The deployment that answers it (dep_...); null when it has none."
                    },
                    "deployment_version": {
                      "anyOf": [
                        {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The version of the deployment it runs on: in test mode the one it started on, in live mode the one live at its last message. Null with no deployment."
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "idle",
                        "replying",
                        "working",
                        "waiting"
                      ],
                      "description": "What the conversation is doing. idle: nothing. replying: Bash is writing its reply. working: work Bash started is running. waiting: Bash waits on an approval, a question or a call to one of your tools."
                    },
                    "metadata": {
                      "type": "object",
                      "propertyNames": {
                        "type": "string"
                      },
                      "additionalProperties": {
                        "type": "string"
                      },
                      "description": "Your labels, as you sent them; empty when you sent none."
                    },
                    "created_at": {
                      "type": "string",
                      "description": "When it started, as an ISO 8601 time."
                    },
                    "last_active_at": {
                      "type": "string",
                      "description": "When a message or its work last changed it, as an ISO 8601 time."
                    },
                    "open_work": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "task_id": {
                            "type": "string",
                            "description": "The task (task_...)."
                          },
                          "title": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "What the work is, in a few words; null until Bash names it."
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "queued",
                              "working",
                              "waiting",
                              "done",
                              "failed"
                            ],
                            "description": "Where a piece of work is. queued: not started yet. working: running on the user's computer. waiting: it waits on an approval or a question. done or failed: it has ended."
                          }
                        },
                        "required": [
                          "task_id",
                          "title",
                          "status"
                        ]
                      },
                      "description": "Work Bash started that has not ended, oldest first."
                    },
                    "open_interactions": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "interaction_id": {
                            "type": "string",
                            "description": "The approval or question, to answer by its id (int_...)."
                          },
                          "task_id": {
                            "type": "string",
                            "description": "The task that asked (task_...)."
                          },
                          "kind": {
                            "type": "string",
                            "description": "What it asks for, as stored: such as tool_permission, ask_question or composio_auth."
                          }
                        },
                        "required": [
                          "interaction_id",
                          "task_id",
                          "kind"
                        ]
                      },
                      "description": "Approvals and questions Bash waits on."
                    },
                    "pending_tool_calls": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "call_id": {
                            "type": "string",
                            "description": "The call, to answer by its id (call_...)."
                          },
                          "name": {
                            "type": "string",
                            "description": "The tool Bash called."
                          },
                          "arguments": {
                            "description": "What Bash passed, matching the input schema of the tool."
                          },
                          "task_id": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "The task that made the call; null when Bash's reply made it."
                          }
                        },
                        "required": [
                          "call_id",
                          "name",
                          "arguments",
                          "task_id"
                        ]
                      },
                      "description": "Calls to your tools that wait on your answer."
                    },
                    "last_event_seq": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991,
                      "description": "The seq of the newest event on its stream: read the conversation, then follow its events after this seq, and you miss nothing."
                    },
                    "cost_usd": {
                      "type": "number",
                      "description": "What it has cost so far, in billed US dollars: Bash's replies, all its work and its voice calls.",
                      "examples": [
                        0.0412
                      ]
                    },
                    "cost_breakdown": {
                      "type": "object",
                      "properties": {
                        "orchestrator": {
                          "type": "number",
                          "description": "Bash's own replies in the conversation, in billed US dollars; 0 on a piece of work."
                        },
                        "intelligence": {
                          "type": "number",
                          "description": "The thinking Bash did while it worked, in billed US dollars."
                        },
                        "tools": {
                          "type": "number",
                          "description": "The tools and apps Bash used, in billed US dollars."
                        },
                        "compute": {
                          "type": "number",
                          "description": "Time on Bash's computer, in billed US dollars."
                        },
                        "background": {
                          "type": "number",
                          "description": "Work Bash did in the background, such as remembering and tidying, in billed US dollars."
                        },
                        "voice": {
                          "type": "number",
                          "description": "Voice call time, in billed US dollars."
                        }
                      },
                      "required": [
                        "orchestrator",
                        "intelligence",
                        "tools",
                        "compute",
                        "background",
                        "voice"
                      ],
                      "description": "The same cost, by kind of spend."
                    }
                  },
                  "required": [
                    "id",
                    "object",
                    "user_id",
                    "deployment_id",
                    "deployment_version",
                    "status",
                    "metadata",
                    "created_at",
                    "last_active_at",
                    "open_work",
                    "open_interactions",
                    "pending_tool_calls",
                    "last_event_seq",
                    "cost_usd",
                    "cost_breakdown"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/conversations/{conversation_id}/messages": {
      "post": {
        "operationId": "postConversationsByConversationIdMessages",
        "summary": "Send a message. Options: context (data for this turn only), attachments, output_schema, success_criteria, tools, hand_off (auto or always). Answers the turn at once; Prefer: wait=N holds for the final answer; stream: true answers this turn's events as text/event-stream and ends when the turn settles.",
        "tags": [
          "Conversations"
        ],
        "x-vestra-line": "ask",
        "x-vestra-scope": "runtime",
        "security": [
          {
            "apiKey": []
          },
          {
            "clientToken": []
          }
        ],
        "parameters": [
          {
            "name": "conversation_id",
            "in": "path",
            "required": true,
            "description": "The conversation's id (`conv_...`).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 255
            },
            "description": "Send the same key to retry this call safely for 24 hours."
          },
          {
            "name": "Prefer",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^wait=\\d{1,3}$"
            },
            "description": "wait=N (N at most 120) holds the call until the turn and its work finish."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "The turn: one message and all it led to (turn_...)."
                    },
                    "object": {
                      "type": "string",
                      "const": "conversation.turn",
                      "description": "Always conversation.turn."
                    },
                    "conversation_id": {
                      "type": "string",
                      "description": "Its conversation (conv_...)."
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "running",
                        "working",
                        "requires_action",
                        "completed",
                        "failed",
                        "stopped"
                      ],
                      "description": "Where one message is. running: Bash is replying. working: the work it started is open. requires_action: it waits on a call to one of your tools. completed, failed or stopped: it has settled."
                    },
                    "reply": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Bash's reply; null until it is written. For a message sent straight to work it is the one line Started work on it."
                    },
                    "answer": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The reply's answer: its final words, the part after any search or lookup Bash made on the way, trimmed; null until the reply is written, or when it said nothing. A turn from before this field holds its whole reply. When Bash went to work, the work's own answer is GET /v1/tasks/{id}'s result.text."
                    },
                    "data": {
                      "anyOf": [
                        {},
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The data you asked for with output_schema, matching it; null when you asked for none."
                    },
                    "outcome": {
                      "anyOf": [
                        {
                          "type": "object",
                          "properties": {
                            "met": {
                              "type": "boolean",
                              "description": "Whether the result meets your success_criteria."
                            },
                            "reason": {
                              "type": "string",
                              "description": "Why, in a sentence."
                            }
                          },
                          "required": [
                            "met",
                            "reason"
                          ]
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Your success_criteria, judged once the turn and its work settle; null when you gave none."
                    },
                    "work": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "task_id": {
                            "type": "string",
                            "description": "The task (task_...)."
                          },
                          "title": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "What the work is, in a few words; null until Bash names it."
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "queued",
                              "working",
                              "waiting",
                              "done",
                              "failed"
                            ],
                            "description": "Where a piece of work is. queued: not started yet. working: running on the user's computer. waiting: it waits on an approval or a question. done or failed: it has ended."
                          },
                          "result": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "Its answer, its final reply, cut to 280 characters; null until it has any. The whole answer is GET /v1/tasks/{id}'s result.text."
                          }
                        },
                        "required": [
                          "task_id",
                          "title",
                          "status",
                          "result"
                        ]
                      },
                      "description": "The work this turn started."
                    },
                    "tool_calls": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "call_id": {
                            "type": "string",
                            "description": "The call, to answer by its id (call_...)."
                          },
                          "name": {
                            "type": "string",
                            "description": "The tool Bash called."
                          },
                          "arguments": {
                            "description": "What Bash passed, matching the input schema of the tool."
                          },
                          "task_id": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "The task that made the call; null when Bash's reply made it."
                          }
                        },
                        "required": [
                          "call_id",
                          "name",
                          "arguments",
                          "task_id"
                        ]
                      },
                      "description": "While it requires action: the calls to your tools it waits on. Empty otherwise."
                    },
                    "error": {
                      "anyOf": [
                        {
                          "type": "object",
                          "properties": {
                            "code": {
                              "type": "string",
                              "description": "Why it failed, as a code: output_invalid (the answer did not match output_schema), work_lost (your answer never reached the work), process_lost (our side was cut off mid-reply; send it again), or Bash's own: credits_exhausted, model_timeout, tool_failed, bad_tool_args, loop_exhausted, unauthorized or internal."
                            },
                            "message": {
                              "type": "string",
                              "description": "What went wrong, in plain words."
                            }
                          },
                          "required": [
                            "code",
                            "message"
                          ]
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Why the turn failed; null unless it did."
                    },
                    "created_at": {
                      "type": "string",
                      "description": "When the message was sent, as an ISO 8601 time."
                    },
                    "finished_at": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "When the turn settled, as an ISO 8601 time; null while it runs."
                    }
                  },
                  "required": [
                    "id",
                    "object",
                    "conversation_id",
                    "status",
                    "reply",
                    "answer",
                    "data",
                    "outcome",
                    "work",
                    "tool_calls",
                    "error",
                    "created_at",
                    "finished_at"
                  ]
                }
              },
              "text/event-stream": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "202": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "The turn: one message and all it led to (turn_...)."
                    },
                    "object": {
                      "type": "string",
                      "const": "conversation.turn",
                      "description": "Always conversation.turn."
                    },
                    "conversation_id": {
                      "type": "string",
                      "description": "Its conversation (conv_...)."
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "running",
                        "working",
                        "requires_action",
                        "completed",
                        "failed",
                        "stopped"
                      ],
                      "description": "Where one message is. running: Bash is replying. working: the work it started is open. requires_action: it waits on a call to one of your tools. completed, failed or stopped: it has settled."
                    },
                    "reply": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Bash's reply; null until it is written. For a message sent straight to work it is the one line Started work on it."
                    },
                    "answer": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The reply's answer: its final words, the part after any search or lookup Bash made on the way, trimmed; null until the reply is written, or when it said nothing. A turn from before this field holds its whole reply. When Bash went to work, the work's own answer is GET /v1/tasks/{id}'s result.text."
                    },
                    "data": {
                      "anyOf": [
                        {},
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The data you asked for with output_schema, matching it; null when you asked for none."
                    },
                    "outcome": {
                      "anyOf": [
                        {
                          "type": "object",
                          "properties": {
                            "met": {
                              "type": "boolean",
                              "description": "Whether the result meets your success_criteria."
                            },
                            "reason": {
                              "type": "string",
                              "description": "Why, in a sentence."
                            }
                          },
                          "required": [
                            "met",
                            "reason"
                          ]
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Your success_criteria, judged once the turn and its work settle; null when you gave none."
                    },
                    "work": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "task_id": {
                            "type": "string",
                            "description": "The task (task_...)."
                          },
                          "title": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "What the work is, in a few words; null until Bash names it."
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "queued",
                              "working",
                              "waiting",
                              "done",
                              "failed"
                            ],
                            "description": "Where a piece of work is. queued: not started yet. working: running on the user's computer. waiting: it waits on an approval or a question. done or failed: it has ended."
                          },
                          "result": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "Its answer, its final reply, cut to 280 characters; null until it has any. The whole answer is GET /v1/tasks/{id}'s result.text."
                          }
                        },
                        "required": [
                          "task_id",
                          "title",
                          "status",
                          "result"
                        ]
                      },
                      "description": "The work this turn started."
                    },
                    "tool_calls": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "call_id": {
                            "type": "string",
                            "description": "The call, to answer by its id (call_...)."
                          },
                          "name": {
                            "type": "string",
                            "description": "The tool Bash called."
                          },
                          "arguments": {
                            "description": "What Bash passed, matching the input schema of the tool."
                          },
                          "task_id": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "The task that made the call; null when Bash's reply made it."
                          }
                        },
                        "required": [
                          "call_id",
                          "name",
                          "arguments",
                          "task_id"
                        ]
                      },
                      "description": "While it requires action: the calls to your tools it waits on. Empty otherwise."
                    },
                    "error": {
                      "anyOf": [
                        {
                          "type": "object",
                          "properties": {
                            "code": {
                              "type": "string",
                              "description": "Why it failed, as a code: output_invalid (the answer did not match output_schema), work_lost (your answer never reached the work), process_lost (our side was cut off mid-reply; send it again), or Bash's own: credits_exhausted, model_timeout, tool_failed, bad_tool_args, loop_exhausted, unauthorized or internal."
                            },
                            "message": {
                              "type": "string",
                              "description": "What went wrong, in plain words."
                            }
                          },
                          "required": [
                            "code",
                            "message"
                          ]
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Why the turn failed; null unless it did."
                    },
                    "created_at": {
                      "type": "string",
                      "description": "When the message was sent, as an ISO 8601 time."
                    },
                    "finished_at": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "When the turn settled, as an ISO 8601 time; null while it runs."
                    }
                  },
                  "required": [
                    "id",
                    "object",
                    "conversation_id",
                    "status",
                    "reply",
                    "answer",
                    "data",
                    "outcome",
                    "work",
                    "tool_calls",
                    "error",
                    "created_at",
                    "finished_at"
                  ]
                }
              },
              "text/event-stream": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "message": {
                    "default": "",
                    "description": "What you or your user say to Bash, in at most 32,000 characters. Default: empty, for a send that carries only attachments.",
                    "examples": [
                      "My 6am flight got cancelled. Book me on the next one."
                    ],
                    "type": "string",
                    "maxLength": 32000
                  },
                  "context": {
                    "description": "Facts for this message only, as JSON. Bash reads them as data, never as instructions.",
                    "examples": [
                      {
                        "booking_reference": "TN-48213",
                        "tier": "gold"
                      }
                    ],
                    "type": "object",
                    "propertyNames": {
                      "type": "string"
                    },
                    "additionalProperties": {}
                  },
                  "attachments": {
                    "description": "Files Bash should read with this message: at most 10.",
                    "maxItems": 10,
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "file_id": {
                          "type": "string",
                          "minLength": 1,
                          "description": "A file you uploaded with POST /v1/files (file_...)."
                        }
                      },
                      "required": [
                        "file_id"
                      ]
                    }
                  },
                  "output_schema": {
                    "description": "A JSON Schema, at most 32 KB, for the data you want back: the turn's data matches it.",
                    "examples": [
                      {
                        "type": "object",
                        "properties": {
                          "flight": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "flight"
                        ]
                      }
                    ],
                    "type": "object",
                    "propertyNames": {
                      "type": "string"
                    },
                    "additionalProperties": {}
                  },
                  "success_criteria": {
                    "description": "What a good result looks like, in your words: when the turn settles, its outcome says whether it was met, and why.",
                    "examples": [
                      "A new booking on a flight that leaves before noon."
                    ],
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 4000
                  },
                  "tools": {
                    "description": "Tools your code answers, for this message only, on top of the deployment's: at most 32.",
                    "maxItems": 32,
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "name": {
                          "type": "string",
                          "pattern": "^(?!mcp__)[a-z][a-z0-9_]{0,63}$",
                          "description": "The tool's name: lowercase letters, digits and underscores, starting with a letter, up to 64.",
                          "examples": [
                            "get_booking"
                          ]
                        },
                        "description": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 1024,
                          "description": "What the tool does, so Bash knows when to call it, up to 1024 characters.",
                          "examples": [
                            "A booking by its PNR"
                          ]
                        },
                        "input_schema": {
                          "type": "object",
                          "propertyNames": {
                            "type": "string"
                          },
                          "additionalProperties": {},
                          "description": "Its arguments, as JSON Schema with `type: object`. Bash's call fills them in.",
                          "examples": [
                            {
                              "type": "object",
                              "properties": {
                                "pnr": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "pnr"
                              ]
                            }
                          ]
                        },
                        "timeout_s": {
                          "default": 120,
                          "description": "Seconds Bash waits for your answer, 5 to 600. Default 120; after it, the call expires.",
                          "type": "integer",
                          "minimum": 5,
                          "maximum": 600
                        },
                        "read_only": {
                          "description": "true: the tool changes nothing (a lookup), so Bash calls it without waiting for the person's yes. Absent: false.",
                          "type": "boolean"
                        },
                        "run_without_asking": {
                          "description": "true: the tool changes something that needs no yes, so Bash calls it without waiting for the person's yes. Absent: false.",
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "name",
                        "description",
                        "input_schema"
                      ]
                    }
                  },
                  "hand_off": {
                    "default": "auto",
                    "type": "string",
                    "enum": [
                      "auto",
                      "always"
                    ],
                    "description": "How a message reaches Bash. auto: Bash reads it, replies, and starts work when the job needs it. always: it goes straight to work, as a task; the reply is the one line Started work on it."
                  },
                  "metadata": {
                    "type": "object",
                    "propertyNames": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 64
                    },
                    "additionalProperties": {
                      "type": "string",
                      "maxLength": 512
                    },
                    "description": "Your own labels, given back as you sent them: at most 32 keys of 1 to 64 characters, each value a string of at most 512. Bash never reads them.",
                    "examples": [
                      {
                        "order_id": "ORD-1042",
                        "channel": "app"
                      }
                    ]
                  },
                  "stream": {
                    "description": "true answers with the turn's events as they happen (text/event-stream), ending when the turn settles. Default: one JSON answer.",
                    "type": "boolean"
                  }
                },
                "additionalProperties": false
              }
            }
          }
        }
      },
      "get": {
        "operationId": "getConversationsByConversationIdMessages",
        "summary": "The conversation, paged: your messages, Bash's replies, and summaries of the work it did.",
        "tags": [
          "Conversations"
        ],
        "x-vestra-line": "ask",
        "x-vestra-scope": "runtime",
        "security": [
          {
            "apiKey": []
          },
          {
            "clientToken": []
          }
        ],
        "parameters": [
          {
            "name": "conversation_id",
            "in": "path",
            "required": true,
            "description": "The conversation's id (`conv_...`).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "default": 20,
              "description": "How many items per page, 1 to 100. Default 20.",
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "description": "Where to go on from: the `next_cursor` of the page before, unchanged. Absent: the first page.",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "The line."
                          },
                          "object": {
                            "type": "string",
                            "const": "conversation.message",
                            "description": "Always conversation.message."
                          },
                          "turn_id": {
                            "type": "string",
                            "description": "The turn it belongs to (turn_...)."
                          },
                          "role": {
                            "type": "string",
                            "enum": [
                              "user",
                              "assistant"
                            ],
                            "description": "user: what was sent. assistant: what Bash said back."
                          },
                          "text": {
                            "type": "string",
                            "description": "The words. A send of tool results reads \"Tool results:\" and the tools it answered."
                          },
                          "work": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "task_id": {
                                  "type": "string",
                                  "description": "The task (task_...)."
                                },
                                "title": {
                                  "anyOf": [
                                    {
                                      "type": "string"
                                    },
                                    {
                                      "type": "null"
                                    }
                                  ],
                                  "description": "What the work is; null until Bash names it."
                                }
                              },
                              "required": [
                                "task_id",
                                "title"
                              ]
                            },
                            "description": "On Bash's line: the work its reply started."
                          },
                          "created_at": {
                            "type": "string",
                            "description": "When it was said, as an ISO 8601 time."
                          }
                        },
                        "required": [
                          "id",
                          "object",
                          "turn_id",
                          "role",
                          "text",
                          "work",
                          "created_at"
                        ]
                      },
                      "description": "The items on this page."
                    },
                    "next_cursor": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Send it as `cursor` for the next page; null on the last page."
                    }
                  },
                  "required": [
                    "data",
                    "next_cursor"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/conversations/{conversation_id}/events": {
      "get": {
        "operationId": "getConversationsByConversationIdEvents",
        "summary": "The one stream (SSE): replies as they are typed, work started and finished, progress, approvals, tool calls, files. Resume with Last-Event-ID. Filter to one task's events with task_id.",
        "tags": [
          "Conversations"
        ],
        "x-vestra-line": "events",
        "x-vestra-scope": "runtime",
        "security": [
          {
            "apiKey": []
          },
          {
            "clientToken": []
          }
        ],
        "parameters": [
          {
            "name": "conversation_id",
            "in": "path",
            "required": true,
            "description": "The conversation's id (`conv_...`).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "format",
            "in": "query",
            "required": false,
            "schema": {
              "default": "sse",
              "description": "sse follows the events as they happen (text/event-stream); json reads one page of them. Default: sse.",
              "type": "string",
              "enum": [
                "sse",
                "json"
              ]
            }
          },
          {
            "name": "after",
            "in": "query",
            "required": false,
            "schema": {
              "description": "Only events after this seq. On the stream, a Last-Event-ID header does the same. Absent: from the first kept event.",
              "examples": [
                41
              ],
              "type": "integer",
              "minimum": 0,
              "maximum": 9007199254740991
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "default": 100,
              "description": "With format json: at most this many events, 1 to 500. Default: 100.",
              "type": "integer",
              "minimum": 1,
              "maximum": 500
            }
          },
          {
            "name": "task_id",
            "in": "query",
            "required": false,
            "schema": {
              "description": "Only this task's events (task_...).",
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "Last-Event-ID",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Resume after this event id."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/event-stream": {
                "schema": {
                  "type": "string"
                }
              },
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "seq": {
                            "type": "integer",
                            "minimum": -9007199254740991,
                            "maximum": 9007199254740991,
                            "description": "Its place on the conversation's stream, counting up: send the last one you saw to pick up after it."
                          },
                          "type": {
                            "type": "string",
                            "enum": [
                              "message.delta",
                              "message.completed",
                              "task.started",
                              "task.progress",
                              "task.completed",
                              "task.failed",
                              "task.stopped",
                              "interaction.created",
                              "interaction.resolved",
                              "interaction.expired",
                              "screen.control",
                              "session.started",
                              "session.ended",
                              "file.created",
                              "routine.fired",
                              "usage.updated",
                              "usage.threshold_reached",
                              "usage.cap_reached",
                              "conversation.status",
                              "user.created",
                              "user.deleted",
                              "connection.completed",
                              "connection.failed",
                              "connection.removed",
                              "memory.observed",
                              "batch.completed",
                              "deployment.version_created",
                              "deployment.promoted",
                              "deployment.rolled_back",
                              "test_run.completed",
                              "key.created",
                              "key.revoked",
                              "error",
                              "ping"
                            ],
                            "description": "What happened, from the one catalog of events: the events reference says what each carries and where it is delivered.",
                            "examples": [
                              "message.completed"
                            ]
                          },
                          "data": {
                            "type": "object",
                            "propertyNames": {
                              "type": "string"
                            },
                            "additionalProperties": {},
                            "description": "What it says: its fields depend on its type, as the events reference lists them."
                          },
                          "created_at": {
                            "type": "string",
                            "description": "When it happened, as an ISO 8601 time."
                          }
                        },
                        "required": [
                          "seq",
                          "type",
                          "data",
                          "created_at"
                        ]
                      },
                      "description": "The events, oldest first."
                    },
                    "next_after": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991,
                      "description": "The seq to send as after for the next page: the last one here, or the after you sent (0 without one) when the page is empty."
                    }
                  },
                  "required": [
                    "data",
                    "next_after"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/conversations/{conversation_id}/stop": {
      "post": {
        "operationId": "postConversationsByConversationIdStop",
        "summary": "Stop the reply and every piece of work the conversation started.",
        "tags": [
          "Conversations"
        ],
        "x-vestra-line": "ask",
        "x-vestra-scope": "runtime",
        "security": [
          {
            "apiKey": []
          },
          {
            "clientToken": []
          }
        ],
        "parameters": [
          {
            "name": "conversation_id",
            "in": "path",
            "required": true,
            "description": "The conversation's id (`conv_...`).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 255
            },
            "description": "Send the same key to retry this call safely for 24 hours."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "The conversation (conv_...)."
                    },
                    "object": {
                      "type": "string",
                      "const": "conversation.stop",
                      "description": "Always conversation.stop."
                    },
                    "stopped_work": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "The tasks the stop ended (task_...)."
                    }
                  },
                  "required": [
                    "id",
                    "object",
                    "stopped_work"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/tasks": {
      "get": {
        "operationId": "getTasks",
        "summary": "All work across your users, or one user's with user_id. Filter by status, deployment, conversation or date too.",
        "tags": [
          "Work"
        ],
        "x-vestra-line": "ask",
        "x-vestra-scope": "runtime",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "default": 20,
              "description": "How many items per page, 1 to 100. Default 20.",
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "description": "Where to go on from: the `next_cursor` of the page before, unchanged. Absent: the first page.",
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "description": "Only tasks with this status.",
              "type": "string",
              "enum": [
                "queued",
                "working",
                "waiting",
                "done",
                "failed"
              ]
            }
          },
          {
            "name": "user_id",
            "in": "query",
            "required": false,
            "schema": {
              "description": "Only this user's, by your id for them.",
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "deployment_id",
            "in": "query",
            "required": false,
            "schema": {
              "description": "Only this deployment's (dep_...).",
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "conversation_id",
            "in": "query",
            "required": false,
            "schema": {
              "description": "Only this conversation's (conv_...).",
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "created_after",
            "in": "query",
            "required": false,
            "schema": {
              "description": "Only tasks started after this ISO 8601 time.",
              "examples": [
                "2026-10-01T00:00:00Z"
              ],
              "type": "string",
              "format": "date-time",
              "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
            }
          },
          {
            "name": "created_before",
            "in": "query",
            "required": false,
            "schema": {
              "description": "Only tasks started before this ISO 8601 time.",
              "type": "string",
              "format": "date-time",
              "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "The task: one piece of work Bash started (task_...).",
                            "examples": [
                              "task_91d"
                            ]
                          },
                          "object": {
                            "type": "string",
                            "const": "task",
                            "description": "Always task."
                          },
                          "user_id": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "Your id for its user; null on your company's own Bash."
                          },
                          "conversation_id": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "The conversation that started it (conv_...); null when none did."
                          },
                          "deployment_id": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "The deployment it runs on (dep_...); null when none."
                          },
                          "deployment_version": {
                            "anyOf": [
                              {
                                "type": "integer",
                                "minimum": -9007199254740991,
                                "maximum": 9007199254740991
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "The version of that deployment it runs on; null when none."
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "queued",
                              "working",
                              "waiting",
                              "done",
                              "failed"
                            ],
                            "description": "queued: not started yet. working: running on the user's computer. waiting: it waits on an approval or a question. done or failed: it has ended."
                          },
                          "title": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "What the work is, in a few words; null until Bash names it."
                          },
                          "progress": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "content": {
                                  "type": "string",
                                  "description": "One step of its plan."
                                },
                                "status": {
                                  "type": "string",
                                  "description": "Where that step is: pending, in_progress or completed."
                                }
                              },
                              "required": [
                                "content",
                                "status"
                              ]
                            },
                            "description": "Its plan, as its latest to-do list; empty when it has none."
                          },
                          "result": {
                            "type": "object",
                            "properties": {
                              "text": {
                                "anyOf": [
                                  {
                                    "type": "string"
                                  },
                                  {
                                    "type": "null"
                                  }
                                ],
                                "description": "The work's answer: its final reply. Read one task for all of it; a list cuts it to 280 characters, as does a task that ended before its answer was recorded. Null until it has any, or when the work ended with no final reply."
                              },
                              "data": {
                                "anyOf": [
                                  {},
                                  {
                                    "type": "null"
                                  }
                                ],
                                "description": "Data it returned for an output_schema; null when it returned none."
                              }
                            },
                            "required": [
                              "text",
                              "data"
                            ],
                            "description": "What the work came to."
                          },
                          "outcome": {
                            "anyOf": [
                              {
                                "type": "object",
                                "properties": {
                                  "met": {
                                    "type": "boolean",
                                    "description": "Whether it met the success criteria."
                                  },
                                  "reason": {
                                    "type": "string",
                                    "description": "Why, in a sentence."
                                  }
                                },
                                "required": [
                                  "met",
                                  "reason"
                                ]
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "Whether it met the success criteria of its message; null when there were none."
                          },
                          "cost_usd": {
                            "type": "number",
                            "description": "What it has cost so far, in billed US dollars; the last charges can land a few seconds after it ends.",
                            "examples": [
                              0.0412
                            ]
                          },
                          "cost_breakdown": {
                            "type": "object",
                            "properties": {
                              "orchestrator": {
                                "type": "number",
                                "description": "Bash's own replies in the conversation, in billed US dollars; 0 on a piece of work."
                              },
                              "intelligence": {
                                "type": "number",
                                "description": "The thinking Bash did while it worked, in billed US dollars."
                              },
                              "tools": {
                                "type": "number",
                                "description": "The tools and apps Bash used, in billed US dollars."
                              },
                              "compute": {
                                "type": "number",
                                "description": "Time on Bash's computer, in billed US dollars."
                              },
                              "background": {
                                "type": "number",
                                "description": "Work Bash did in the background, such as remembering and tidying, in billed US dollars."
                              },
                              "voice": {
                                "type": "number",
                                "description": "Voice call time, in billed US dollars."
                              }
                            },
                            "required": [
                              "orchestrator",
                              "intelligence",
                              "tools",
                              "compute",
                              "background",
                              "voice"
                            ],
                            "description": "The same cost, by kind of spend."
                          },
                          "created_at": {
                            "type": "string",
                            "description": "When it started, as an ISO 8601 time."
                          },
                          "updated_at": {
                            "type": "string",
                            "description": "When it last changed, as an ISO 8601 time."
                          }
                        },
                        "required": [
                          "id",
                          "object",
                          "user_id",
                          "conversation_id",
                          "deployment_id",
                          "deployment_version",
                          "status",
                          "title",
                          "progress",
                          "result",
                          "outcome",
                          "cost_usd",
                          "cost_breakdown",
                          "created_at",
                          "updated_at"
                        ]
                      },
                      "description": "The items on this page."
                    },
                    "next_cursor": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Send it as `cursor` for the next page; null on the last page."
                    }
                  },
                  "required": [
                    "data",
                    "next_cursor"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/tasks/{task_id}": {
      "get": {
        "operationId": "getTasksByTaskId",
        "summary": "Status, title, the progress list, the result (text, and data when an output_schema was set), the outcome, cost so far.",
        "tags": [
          "Work"
        ],
        "x-vestra-line": "ask",
        "x-vestra-scope": "runtime",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "task_id",
            "in": "path",
            "required": true,
            "description": "The piece of work's id (`task_...`).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "The task: one piece of work Bash started (task_...).",
                      "examples": [
                        "task_91d"
                      ]
                    },
                    "object": {
                      "type": "string",
                      "const": "task",
                      "description": "Always task."
                    },
                    "user_id": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Your id for its user; null on your company's own Bash."
                    },
                    "conversation_id": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The conversation that started it (conv_...); null when none did."
                    },
                    "deployment_id": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The deployment it runs on (dep_...); null when none."
                    },
                    "deployment_version": {
                      "anyOf": [
                        {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The version of that deployment it runs on; null when none."
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "queued",
                        "working",
                        "waiting",
                        "done",
                        "failed"
                      ],
                      "description": "queued: not started yet. working: running on the user's computer. waiting: it waits on an approval or a question. done or failed: it has ended."
                    },
                    "title": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "What the work is, in a few words; null until Bash names it."
                    },
                    "progress": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "content": {
                            "type": "string",
                            "description": "One step of its plan."
                          },
                          "status": {
                            "type": "string",
                            "description": "Where that step is: pending, in_progress or completed."
                          }
                        },
                        "required": [
                          "content",
                          "status"
                        ]
                      },
                      "description": "Its plan, as its latest to-do list; empty when it has none."
                    },
                    "result": {
                      "type": "object",
                      "properties": {
                        "text": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ],
                          "description": "The work's answer: its final reply. Read one task for all of it; a list cuts it to 280 characters, as does a task that ended before its answer was recorded. Null until it has any, or when the work ended with no final reply."
                        },
                        "data": {
                          "anyOf": [
                            {},
                            {
                              "type": "null"
                            }
                          ],
                          "description": "Data it returned for an output_schema; null when it returned none."
                        }
                      },
                      "required": [
                        "text",
                        "data"
                      ],
                      "description": "What the work came to."
                    },
                    "outcome": {
                      "anyOf": [
                        {
                          "type": "object",
                          "properties": {
                            "met": {
                              "type": "boolean",
                              "description": "Whether it met the success criteria."
                            },
                            "reason": {
                              "type": "string",
                              "description": "Why, in a sentence."
                            }
                          },
                          "required": [
                            "met",
                            "reason"
                          ]
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Whether it met the success criteria of its message; null when there were none."
                    },
                    "cost_usd": {
                      "type": "number",
                      "description": "What it has cost so far, in billed US dollars; the last charges can land a few seconds after it ends.",
                      "examples": [
                        0.0412
                      ]
                    },
                    "cost_breakdown": {
                      "type": "object",
                      "properties": {
                        "orchestrator": {
                          "type": "number",
                          "description": "Bash's own replies in the conversation, in billed US dollars; 0 on a piece of work."
                        },
                        "intelligence": {
                          "type": "number",
                          "description": "The thinking Bash did while it worked, in billed US dollars."
                        },
                        "tools": {
                          "type": "number",
                          "description": "The tools and apps Bash used, in billed US dollars."
                        },
                        "compute": {
                          "type": "number",
                          "description": "Time on Bash's computer, in billed US dollars."
                        },
                        "background": {
                          "type": "number",
                          "description": "Work Bash did in the background, such as remembering and tidying, in billed US dollars."
                        },
                        "voice": {
                          "type": "number",
                          "description": "Voice call time, in billed US dollars."
                        }
                      },
                      "required": [
                        "orchestrator",
                        "intelligence",
                        "tools",
                        "compute",
                        "background",
                        "voice"
                      ],
                      "description": "The same cost, by kind of spend."
                    },
                    "created_at": {
                      "type": "string",
                      "description": "When it started, as an ISO 8601 time."
                    },
                    "updated_at": {
                      "type": "string",
                      "description": "When it last changed, as an ISO 8601 time."
                    }
                  },
                  "required": [
                    "id",
                    "object",
                    "user_id",
                    "conversation_id",
                    "deployment_id",
                    "deployment_version",
                    "status",
                    "title",
                    "progress",
                    "result",
                    "outcome",
                    "cost_usd",
                    "cost_breakdown",
                    "created_at",
                    "updated_at"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteTasksByTaskId",
        "summary": "Delete it and its outputs.",
        "tags": [
          "Work"
        ],
        "x-vestra-line": "ask",
        "x-vestra-scope": "runtime",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "task_id",
            "in": "path",
            "required": true,
            "description": "The piece of work's id (`task_...`).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "The task (task_...)."
                    },
                    "object": {
                      "type": "string",
                      "const": "task",
                      "description": "Always task."
                    },
                    "deleted": {
                      "type": "boolean",
                      "const": true,
                      "description": "Always true: it is gone, stopped first if it was running."
                    }
                  },
                  "required": [
                    "id",
                    "object",
                    "deleted"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/tasks/{task_id}/trace": {
      "get": {
        "operationId": "getTasksByTaskIdTrace",
        "summary": "Every step: tools called with a summary of inputs and outputs, timings, tokens and cost per turn.",
        "tags": [
          "Work"
        ],
        "x-vestra-line": "events",
        "x-vestra-scope": "runtime",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "task_id",
            "in": "path",
            "required": true,
            "description": "The piece of work's id (`task_...`).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "type": "string",
                      "const": "task_trace",
                      "description": "Always task_trace."
                    },
                    "task_id": {
                      "type": "string",
                      "description": "The task (task_...)."
                    },
                    "steps": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "tool_use_id": {
                            "type": "string",
                            "description": "The step: one use of a tool."
                          },
                          "name": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "The tool Bash used; null when it was not recorded."
                          },
                          "input_summary": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "What Bash did with it, in a line: never the raw input. Null when there is none."
                          },
                          "output_summary": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "What came back, in a line; null when there is none."
                          },
                          "is_error": {
                            "type": "boolean",
                            "description": "Whether the step failed."
                          },
                          "started_at": {
                            "type": "string",
                            "description": "When it started, as an ISO 8601 time."
                          },
                          "finished_at": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "When it finished, as an ISO 8601 time; null while running."
                          },
                          "duration_ms": {
                            "anyOf": [
                              {
                                "type": "number"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "How long it took, in milliseconds; null while running."
                          }
                        },
                        "required": [
                          "tool_use_id",
                          "name",
                          "input_summary",
                          "output_summary",
                          "is_error",
                          "started_at",
                          "finished_at",
                          "duration_ms"
                        ]
                      },
                      "description": "Every tool Bash used, in order."
                    },
                    "turns": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "turn_id": {
                            "type": "string",
                            "description": "The model turn: one call to the model."
                          },
                          "model": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "The model that answered; null when it was not recorded."
                          },
                          "input_tokens": {
                            "type": "number",
                            "description": "Tokens the model read."
                          },
                          "output_tokens": {
                            "type": "number",
                            "description": "Tokens the model wrote."
                          },
                          "cache_read_tokens": {
                            "type": "number",
                            "description": "Of the tokens it read, how many came from the cache, at a lower price."
                          },
                          "cost_usd": {
                            "type": "number",
                            "description": "What this turn cost, in billed US dollars."
                          },
                          "duration_ms": {
                            "anyOf": [
                              {
                                "type": "number"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "How long it took, in milliseconds; null when not recorded."
                          },
                          "status": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "How it ended, as recorded; null when not recorded."
                          },
                          "started_at": {
                            "type": "string",
                            "description": "When it started, as an ISO 8601 time."
                          }
                        },
                        "required": [
                          "turn_id",
                          "model",
                          "input_tokens",
                          "output_tokens",
                          "cache_read_tokens",
                          "cost_usd",
                          "duration_ms",
                          "status",
                          "started_at"
                        ]
                      },
                      "description": "Every call to the model, in order, with its tokens and cost."
                    },
                    "totals": {
                      "type": "object",
                      "properties": {
                        "input_tokens": {
                          "type": "number",
                          "description": "All tokens read."
                        },
                        "output_tokens": {
                          "type": "number",
                          "description": "All tokens written."
                        },
                        "cost_usd": {
                          "type": "number",
                          "description": "What every turn cost together, in billed US dollars."
                        }
                      },
                      "required": [
                        "input_tokens",
                        "output_tokens",
                        "cost_usd"
                      ],
                      "description": "The turns added up."
                    }
                  },
                  "required": [
                    "object",
                    "task_id",
                    "steps",
                    "turns",
                    "totals"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/tasks/{task_id}/stop": {
      "post": {
        "operationId": "postTasksByTaskIdStop",
        "summary": "Stop this piece of work only.",
        "tags": [
          "Work"
        ],
        "x-vestra-line": "ask",
        "x-vestra-scope": "runtime",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "task_id",
            "in": "path",
            "required": true,
            "description": "The piece of work's id (`task_...`).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 255
            },
            "description": "Send the same key to retry this call safely for 24 hours."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "task": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "The task: one piece of work Bash started (task_...).",
                          "examples": [
                            "task_91d"
                          ]
                        },
                        "object": {
                          "type": "string",
                          "const": "task",
                          "description": "Always task."
                        },
                        "user_id": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ],
                          "description": "Your id for its user; null on your company's own Bash."
                        },
                        "conversation_id": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ],
                          "description": "The conversation that started it (conv_...); null when none did."
                        },
                        "deployment_id": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ],
                          "description": "The deployment it runs on (dep_...); null when none."
                        },
                        "deployment_version": {
                          "anyOf": [
                            {
                              "type": "integer",
                              "minimum": -9007199254740991,
                              "maximum": 9007199254740991
                            },
                            {
                              "type": "null"
                            }
                          ],
                          "description": "The version of that deployment it runs on; null when none."
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "queued",
                            "working",
                            "waiting",
                            "done",
                            "failed"
                          ],
                          "description": "queued: not started yet. working: running on the user's computer. waiting: it waits on an approval or a question. done or failed: it has ended."
                        },
                        "title": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ],
                          "description": "What the work is, in a few words; null until Bash names it."
                        },
                        "progress": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "content": {
                                "type": "string",
                                "description": "One step of its plan."
                              },
                              "status": {
                                "type": "string",
                                "description": "Where that step is: pending, in_progress or completed."
                              }
                            },
                            "required": [
                              "content",
                              "status"
                            ]
                          },
                          "description": "Its plan, as its latest to-do list; empty when it has none."
                        },
                        "result": {
                          "type": "object",
                          "properties": {
                            "text": {
                              "anyOf": [
                                {
                                  "type": "string"
                                },
                                {
                                  "type": "null"
                                }
                              ],
                              "description": "The work's answer: its final reply. Read one task for all of it; a list cuts it to 280 characters, as does a task that ended before its answer was recorded. Null until it has any, or when the work ended with no final reply."
                            },
                            "data": {
                              "anyOf": [
                                {},
                                {
                                  "type": "null"
                                }
                              ],
                              "description": "Data it returned for an output_schema; null when it returned none."
                            }
                          },
                          "required": [
                            "text",
                            "data"
                          ],
                          "description": "What the work came to."
                        },
                        "outcome": {
                          "anyOf": [
                            {
                              "type": "object",
                              "properties": {
                                "met": {
                                  "type": "boolean",
                                  "description": "Whether it met the success criteria."
                                },
                                "reason": {
                                  "type": "string",
                                  "description": "Why, in a sentence."
                                }
                              },
                              "required": [
                                "met",
                                "reason"
                              ]
                            },
                            {
                              "type": "null"
                            }
                          ],
                          "description": "Whether it met the success criteria of its message; null when there were none."
                        },
                        "cost_usd": {
                          "type": "number",
                          "description": "What it has cost so far, in billed US dollars; the last charges can land a few seconds after it ends.",
                          "examples": [
                            0.0412
                          ]
                        },
                        "cost_breakdown": {
                          "type": "object",
                          "properties": {
                            "orchestrator": {
                              "type": "number",
                              "description": "Bash's own replies in the conversation, in billed US dollars; 0 on a piece of work."
                            },
                            "intelligence": {
                              "type": "number",
                              "description": "The thinking Bash did while it worked, in billed US dollars."
                            },
                            "tools": {
                              "type": "number",
                              "description": "The tools and apps Bash used, in billed US dollars."
                            },
                            "compute": {
                              "type": "number",
                              "description": "Time on Bash's computer, in billed US dollars."
                            },
                            "background": {
                              "type": "number",
                              "description": "Work Bash did in the background, such as remembering and tidying, in billed US dollars."
                            },
                            "voice": {
                              "type": "number",
                              "description": "Voice call time, in billed US dollars."
                            }
                          },
                          "required": [
                            "orchestrator",
                            "intelligence",
                            "tools",
                            "compute",
                            "background",
                            "voice"
                          ],
                          "description": "The same cost, by kind of spend."
                        },
                        "created_at": {
                          "type": "string",
                          "description": "When it started, as an ISO 8601 time."
                        },
                        "updated_at": {
                          "type": "string",
                          "description": "When it last changed, as an ISO 8601 time."
                        }
                      },
                      "required": [
                        "id",
                        "object",
                        "user_id",
                        "conversation_id",
                        "deployment_id",
                        "deployment_version",
                        "status",
                        "title",
                        "progress",
                        "result",
                        "outcome",
                        "cost_usd",
                        "cost_breakdown",
                        "created_at",
                        "updated_at"
                      ],
                      "description": "The task, after the stop."
                    },
                    "delivered": {
                      "type": "boolean",
                      "description": "Whether the stop surely reached the work."
                    },
                    "reason": {
                      "anyOf": [
                        {
                          "type": "string",
                          "enum": [
                            "local_relay_down",
                            "nothing_to_kill",
                            "kill_not_permitted",
                            "not_running"
                          ]
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Why the stop did not land; null when it did. not_running: it was at rest, so nothing was sent. nothing_to_kill: nothing was running. local_relay_down: it runs on the user's own computer, which cannot be reached. kill_not_permitted: it could not be reached, so it may still be running."
                    }
                  },
                  "required": [
                    "task",
                    "delivered",
                    "reason"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/interactions": {
      "get": {
        "operationId": "getInteractions",
        "summary": "Everything Bash waits on, across your users: approvals, questions, app connections, hand-offs, and calls to your client tools (type tool_call). Filter by user_id, conversation_id, task_id, type or status (pending by default).",
        "tags": [
          "Interactions"
        ],
        "x-vestra-line": "answer",
        "x-vestra-scope": "runtime",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "default": 20,
              "description": "How many items per page, 1 to 100. Default 20.",
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "description": "Where to go on from: the `next_cursor` of the page before, unchanged. Absent: the first page.",
              "type": "string"
            }
          },
          {
            "name": "user_id",
            "in": "query",
            "required": false,
            "schema": {
              "description": "Only this user's, by your id for them.",
              "type": "string",
              "pattern": "^[A-Za-z0-9][A-Za-z0-9._:@-]{0,127}$",
              "examples": [
                "traveller-42"
              ]
            }
          },
          {
            "name": "conversation_id",
            "in": "query",
            "required": false,
            "schema": {
              "description": "Only this conversation's (conv_...).",
              "type": "string",
              "minLength": 1,
              "maxLength": 256
            }
          },
          {
            "name": "task_id",
            "in": "query",
            "required": false,
            "schema": {
              "description": "Only this task's (task_...).",
              "type": "string",
              "minLength": 1,
              "maxLength": 256
            }
          },
          {
            "name": "type",
            "in": "query",
            "required": false,
            "schema": {
              "description": "Only this type. Absent: every type, calls to your tools included. tool_call: those calls alone.",
              "type": "string",
              "enum": [
                "approval",
                "question",
                "connect",
                "handoff",
                "tool_call"
              ]
            }
          },
          {
            "name": "kind",
            "in": "query",
            "required": false,
            "schema": {
              "description": "Only this kind.",
              "type": "string",
              "enum": [
                "ask_question",
                "composio_auth",
                "tool_permission",
                "credit_approval",
                "exit_plan",
                "custom",
                "hands_approval",
                "plan_limit"
              ]
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "default": "pending",
              "description": "Only this status. Default: pending, what Bash waits on now.",
              "type": "string",
              "enum": [
                "pending",
                "resolved",
                "cancelled",
                "expired"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "object": {
                            "type": "string",
                            "const": "interaction",
                            "description": "Always interaction."
                          },
                          "id": {
                            "type": "string",
                            "description": "The interaction, to answer by its id (int_...; call_... for a call to your tool).",
                            "examples": [
                              "int_3j9"
                            ]
                          },
                          "user_id": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "Your id for the user it is for; null on your company's own Bash."
                          },
                          "task_id": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "The task that asked (task_...); null for a call to your tool that Bash's reply made."
                          },
                          "conversation_id": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "Its conversation (conv_...); null when its task has none."
                          },
                          "kind": {
                            "type": "string",
                            "enum": [
                              "ask_question",
                              "composio_auth",
                              "tool_permission",
                              "credit_approval",
                              "exit_plan",
                              "custom",
                              "hands_approval",
                              "plan_limit"
                            ],
                            "description": "What exactly Bash waits on. ask_question: a question, or a hand-off. composio_auth: connecting an app. tool_permission: a step with a tool. credit_approval: spending on a paid tool. exit_plan: a plan before it starts. hands_approval: an action on a computer, approved in person. plan_limit: a plan's limit ran out (read only). custom: anything else, named by details.renderer."
                          },
                          "type": {
                            "type": "string",
                            "enum": [
                              "approval",
                              "question",
                              "connect",
                              "handoff",
                              "tool_call"
                            ],
                            "description": "What kind of answer it takes. approval: yes or no. question: an answer to each question. connect: your user connects an app. handoff: a person does one thing, then says so. tool_call: your tool returns an output or an error."
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "pending",
                              "resolved",
                              "cancelled",
                              "expired"
                            ],
                            "description": "pending: Bash waits on it. resolved: it was answered. cancelled: it was withdrawn before an answer. expired: nobody answered in time."
                          },
                          "summary": {
                            "type": "string",
                            "description": "What Bash wants, in a phrase to show your user.",
                            "examples": [
                              "pay, amount $500.00",
                              "Connect Gmail"
                            ]
                          },
                          "moves_money": {
                            "anyOf": [
                              {
                                "type": "boolean"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "Whether saying yes spends money, such as a payment. null on the card for one of your own tools (a function of yours, or a tool of your MCP servers): your app knows what your tools cost, and Vestra cannot."
                          },
                          "requires_present_user": {
                            "type": "boolean",
                            "description": "Whether a yes needs present_user: true, meaning the person who saw it said yes: true for a payment, and for an action approved in person."
                          },
                          "nonce": {
                            "description": "For an action approved in person (hands_approval) only: send it back with your yes.",
                            "type": "string"
                          },
                          "questions": {
                            "description": "For a question or a hand-off: what Bash asks, one or more questions.",
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "question": {
                                  "type": "string",
                                  "description": "The question, as Bash asks it.",
                                  "examples": [
                                    "Which flight should I book?"
                                  ]
                                },
                                "header": {
                                  "type": "string",
                                  "description": "A short label for it, for a heading or a chip; empty when Bash gave none."
                                },
                                "options": {
                                  "type": "array",
                                  "items": {
                                    "type": "object",
                                    "properties": {
                                      "label": {
                                        "type": "string",
                                        "description": "An answer your user can pick."
                                      },
                                      "description": {
                                        "type": "string",
                                        "description": "A line more about that answer; empty when there is none."
                                      }
                                    },
                                    "required": [
                                      "label",
                                      "description"
                                    ]
                                  },
                                  "description": "Answers Bash suggests; your user may still answer in their own words. Empty when it suggests none."
                                },
                                "multi_select": {
                                  "type": "boolean",
                                  "description": "Whether more than one option may be picked."
                                }
                              },
                              "required": [
                                "question",
                                "header",
                                "options",
                                "multi_select"
                              ]
                            }
                          },
                          "frame_url": {
                            "description": "For a hand-off, on a single read only (never in lists): the page Bash was on when it asked, as a JPEG data URI.",
                            "type": "string"
                          },
                          "browser": {
                            "description": "For a hand-off in the browser: open a session with a screen (POST /v1/sessions) so a person can do it.",
                            "type": "object",
                            "properties": {
                              "suggested_mode": {
                                "type": "string",
                                "const": "control",
                                "description": "Open the screen with control, so the person can take the wheel."
                              },
                              "url": {
                                "anyOf": [
                                  {
                                    "type": "string"
                                  },
                                  {
                                    "type": "null"
                                  }
                                ],
                                "description": "The page Bash's browser is on; null when it did not say."
                              }
                            },
                            "required": [
                              "suggested_mode",
                              "url"
                            ]
                          },
                          "details": {
                            "type": "object",
                            "propertyNames": {
                              "type": "string"
                            },
                            "additionalProperties": {},
                            "description": "A few named facts for its kind, safe to show: such as tool_name and rows for a tool step (with server for a tool of an MCP server, and its arguments as rows), or app for a connection. Never the raw request."
                          },
                          "outcome": {
                            "anyOf": [
                              {
                                "type": "object",
                                "properties": {
                                  "decision": {
                                    "type": "string",
                                    "enum": [
                                      "approved",
                                      "denied",
                                      "answered",
                                      "cancelled",
                                      "expired"
                                    ],
                                    "description": "How it ended."
                                  },
                                  "answers": {
                                    "description": "For an answered question: the answer to each question, in order.",
                                    "type": "array",
                                    "items": {
                                      "type": "string"
                                    }
                                  },
                                  "reason": {
                                    "description": "For a denial: why, when one was recorded.",
                                    "type": "string"
                                  },
                                  "message": {
                                    "description": "For a denial: the note that was sent with the no, when there was one.",
                                    "type": "string"
                                  }
                                },
                                "required": [
                                  "decision"
                                ]
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "How it ended; null while it is pending."
                          },
                          "created_at": {
                            "type": "string",
                            "description": "When Bash asked, as an ISO 8601 time."
                          },
                          "expires_at": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "When it expires unanswered, as an ISO 8601 time; null when it never does."
                          },
                          "resolved_at": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "When it was answered, withdrawn or expired, as an ISO 8601 time; null while pending."
                          }
                        },
                        "required": [
                          "object",
                          "id",
                          "user_id",
                          "task_id",
                          "conversation_id",
                          "kind",
                          "type",
                          "status",
                          "summary",
                          "moves_money",
                          "requires_present_user",
                          "details",
                          "outcome",
                          "created_at",
                          "expires_at",
                          "resolved_at"
                        ]
                      },
                      "description": "The items on this page."
                    },
                    "next_cursor": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Send it as `cursor` for the next page; null on the last page."
                    }
                  },
                  "required": [
                    "data",
                    "next_cursor"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/interactions/{interaction_id}": {
      "get": {
        "operationId": "getInteractionsByInteractionId",
        "summary": "One item, by its int_ or call_ id: its type (approval, question, connect, handoff, tool_call), what Bash wants to do, the options, when it expires. A handoff carries a snapshot of the page.",
        "tags": [
          "Interactions"
        ],
        "x-vestra-line": "answer",
        "x-vestra-scope": "runtime",
        "security": [
          {
            "apiKey": []
          },
          {
            "clientToken": []
          }
        ],
        "parameters": [
          {
            "name": "interaction_id",
            "in": "path",
            "required": true,
            "description": "What Bash waits on, by its id: `int_...`, or `call_...` for a call to your tool.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "type": "string",
                      "const": "interaction",
                      "description": "Always interaction."
                    },
                    "id": {
                      "type": "string",
                      "description": "The interaction, to answer by its id (int_...; call_... for a call to your tool).",
                      "examples": [
                        "int_3j9"
                      ]
                    },
                    "user_id": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Your id for the user it is for; null on your company's own Bash."
                    },
                    "task_id": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The task that asked (task_...); null for a call to your tool that Bash's reply made."
                    },
                    "conversation_id": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Its conversation (conv_...); null when its task has none."
                    },
                    "kind": {
                      "type": "string",
                      "enum": [
                        "ask_question",
                        "composio_auth",
                        "tool_permission",
                        "credit_approval",
                        "exit_plan",
                        "custom",
                        "hands_approval",
                        "plan_limit"
                      ],
                      "description": "What exactly Bash waits on. ask_question: a question, or a hand-off. composio_auth: connecting an app. tool_permission: a step with a tool. credit_approval: spending on a paid tool. exit_plan: a plan before it starts. hands_approval: an action on a computer, approved in person. plan_limit: a plan's limit ran out (read only). custom: anything else, named by details.renderer."
                    },
                    "type": {
                      "type": "string",
                      "enum": [
                        "approval",
                        "question",
                        "connect",
                        "handoff",
                        "tool_call"
                      ],
                      "description": "What kind of answer it takes. approval: yes or no. question: an answer to each question. connect: your user connects an app. handoff: a person does one thing, then says so. tool_call: your tool returns an output or an error."
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "pending",
                        "resolved",
                        "cancelled",
                        "expired"
                      ],
                      "description": "pending: Bash waits on it. resolved: it was answered. cancelled: it was withdrawn before an answer. expired: nobody answered in time."
                    },
                    "summary": {
                      "type": "string",
                      "description": "What Bash wants, in a phrase to show your user.",
                      "examples": [
                        "pay, amount $500.00",
                        "Connect Gmail"
                      ]
                    },
                    "moves_money": {
                      "anyOf": [
                        {
                          "type": "boolean"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Whether saying yes spends money, such as a payment. null on the card for one of your own tools (a function of yours, or a tool of your MCP servers): your app knows what your tools cost, and Vestra cannot."
                    },
                    "requires_present_user": {
                      "type": "boolean",
                      "description": "Whether a yes needs present_user: true, meaning the person who saw it said yes: true for a payment, and for an action approved in person."
                    },
                    "nonce": {
                      "description": "For an action approved in person (hands_approval) only: send it back with your yes.",
                      "type": "string"
                    },
                    "questions": {
                      "description": "For a question or a hand-off: what Bash asks, one or more questions.",
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "question": {
                            "type": "string",
                            "description": "The question, as Bash asks it.",
                            "examples": [
                              "Which flight should I book?"
                            ]
                          },
                          "header": {
                            "type": "string",
                            "description": "A short label for it, for a heading or a chip; empty when Bash gave none."
                          },
                          "options": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "label": {
                                  "type": "string",
                                  "description": "An answer your user can pick."
                                },
                                "description": {
                                  "type": "string",
                                  "description": "A line more about that answer; empty when there is none."
                                }
                              },
                              "required": [
                                "label",
                                "description"
                              ]
                            },
                            "description": "Answers Bash suggests; your user may still answer in their own words. Empty when it suggests none."
                          },
                          "multi_select": {
                            "type": "boolean",
                            "description": "Whether more than one option may be picked."
                          }
                        },
                        "required": [
                          "question",
                          "header",
                          "options",
                          "multi_select"
                        ]
                      }
                    },
                    "frame_url": {
                      "description": "For a hand-off, on a single read only (never in lists): the page Bash was on when it asked, as a JPEG data URI.",
                      "type": "string"
                    },
                    "browser": {
                      "description": "For a hand-off in the browser: open a session with a screen (POST /v1/sessions) so a person can do it.",
                      "type": "object",
                      "properties": {
                        "suggested_mode": {
                          "type": "string",
                          "const": "control",
                          "description": "Open the screen with control, so the person can take the wheel."
                        },
                        "url": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ],
                          "description": "The page Bash's browser is on; null when it did not say."
                        }
                      },
                      "required": [
                        "suggested_mode",
                        "url"
                      ]
                    },
                    "details": {
                      "type": "object",
                      "propertyNames": {
                        "type": "string"
                      },
                      "additionalProperties": {},
                      "description": "A few named facts for its kind, safe to show: such as tool_name and rows for a tool step (with server for a tool of an MCP server, and its arguments as rows), or app for a connection. Never the raw request."
                    },
                    "outcome": {
                      "anyOf": [
                        {
                          "type": "object",
                          "properties": {
                            "decision": {
                              "type": "string",
                              "enum": [
                                "approved",
                                "denied",
                                "answered",
                                "cancelled",
                                "expired"
                              ],
                              "description": "How it ended."
                            },
                            "answers": {
                              "description": "For an answered question: the answer to each question, in order.",
                              "type": "array",
                              "items": {
                                "type": "string"
                              }
                            },
                            "reason": {
                              "description": "For a denial: why, when one was recorded.",
                              "type": "string"
                            },
                            "message": {
                              "description": "For a denial: the note that was sent with the no, when there was one.",
                              "type": "string"
                            }
                          },
                          "required": [
                            "decision"
                          ]
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "How it ended; null while it is pending."
                    },
                    "created_at": {
                      "type": "string",
                      "description": "When Bash asked, as an ISO 8601 time."
                    },
                    "expires_at": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "When it expires unanswered, as an ISO 8601 time; null when it never does."
                    },
                    "resolved_at": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "When it was answered, withdrawn or expired, as an ISO 8601 time; null while pending."
                    }
                  },
                  "required": [
                    "object",
                    "id",
                    "user_id",
                    "task_id",
                    "conversation_id",
                    "kind",
                    "type",
                    "status",
                    "summary",
                    "moves_money",
                    "requires_present_user",
                    "details",
                    "outcome",
                    "created_at",
                    "expires_at",
                    "resolved_at"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/interactions/{interaction_id}/answer": {
      "post": {
        "operationId": "postInteractionsByInteractionIdAnswer",
        "summary": "Answer it, whatever it is. An approval takes approve (true or false), a question answers or approve: false, a hand-off done, could_not or not_now (or answers, when it asks for a value such as a code), a client tool call output or error. A money or account approval, and the yes to a company action (a tool of your MCP servers, or a function of yours that is not read-only or run without asking), must carry present_user: true. A body that fits another kind is 400 answer_mismatch.",
        "tags": [
          "Interactions"
        ],
        "x-vestra-line": "answer",
        "x-vestra-scope": "runtime",
        "security": [
          {
            "apiKey": []
          },
          {
            "clientToken": []
          }
        ],
        "parameters": [
          {
            "name": "interaction_id",
            "in": "path",
            "required": true,
            "description": "What Bash waits on, by its id: `int_...`, or `call_...` for a call to your tool.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 255
            },
            "description": "Send the same key to retry this call safely for 24 hours."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "What you answered (int_... or call_...)."
                    },
                    "object": {
                      "type": "string",
                      "const": "interaction",
                      "description": "Always interaction."
                    },
                    "type": {
                      "type": "string",
                      "enum": [
                        "approval",
                        "question",
                        "connect",
                        "handoff",
                        "tool_call"
                      ],
                      "description": "What kind of answer it takes. approval: yes or no. question: an answer to each question. connect: your user connects an app. handoff: a person does one thing, then says so. tool_call: your tool returns an output or an error."
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "resolved",
                        "completed",
                        "failed"
                      ],
                      "description": "resolved: Bash has your answer and carries on. For a call to your tool: completed with your output, or failed with your error."
                    }
                  },
                  "required": [
                    "id",
                    "object",
                    "type",
                    "status"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "anyOf": [
                  {
                    "type": "object",
                    "properties": {
                      "approve": {
                        "type": "boolean",
                        "description": "Yes or no to an approval. For a connection, only no: your user connects the app with POST /v1/connections, and the item settles itself. false also skips a question."
                      },
                      "present_user": {
                        "description": "true when the person who saw it said yes. A yes that moves money, or is approved in person, needs it.",
                        "type": "boolean"
                      },
                      "message": {
                        "description": "With a no: a note for Bash, in at most 500 characters.",
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 500
                      },
                      "nonce": {
                        "description": "For an action approved in person: the interaction's nonce, sent back.",
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 4096
                      }
                    },
                    "required": [
                      "approve"
                    ],
                    "additionalProperties": false
                  },
                  {
                    "type": "object",
                    "properties": {
                      "answers": {
                        "minItems": 1,
                        "maxItems": 4,
                        "type": "array",
                        "items": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 4000
                        },
                        "description": "One answer per question, in order: at most 4, each at most 4,000 characters."
                      }
                    },
                    "required": [
                      "answers"
                    ],
                    "additionalProperties": false
                  },
                  {
                    "type": "object",
                    "properties": {
                      "done": {
                        "type": "boolean",
                        "const": true,
                        "description": "For a hand-off: the person did it."
                      }
                    },
                    "required": [
                      "done"
                    ],
                    "additionalProperties": false
                  },
                  {
                    "type": "object",
                    "properties": {
                      "could_not": {
                        "type": "boolean",
                        "const": true,
                        "description": "For a hand-off: the person tried and could not."
                      }
                    },
                    "required": [
                      "could_not"
                    ],
                    "additionalProperties": false
                  },
                  {
                    "type": "object",
                    "properties": {
                      "not_now": {
                        "type": "boolean",
                        "const": true,
                        "description": "For a hand-off: not now; Bash carries on without it."
                      }
                    },
                    "required": [
                      "not_now"
                    ],
                    "additionalProperties": false
                  },
                  {
                    "type": "object",
                    "properties": {
                      "output": {
                        "description": "For a call to your tool: what it returned, as any JSON."
                      }
                    },
                    "required": [
                      "output"
                    ],
                    "additionalProperties": false
                  },
                  {
                    "type": "object",
                    "properties": {
                      "error": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 4000,
                        "description": "For a call to your tool: why it failed, in at most 4,000 characters."
                      }
                    },
                    "required": [
                      "error"
                    ],
                    "additionalProperties": false
                  }
                ]
              }
            }
          }
        }
      }
    },
    "/v1/interactions/{interaction_id}/cancel": {
      "post": {
        "operationId": "postInteractionsByInteractionIdCancel",
        "summary": "Withdraw it. The task carries on without that action.",
        "tags": [
          "Interactions"
        ],
        "x-vestra-line": "answer",
        "x-vestra-scope": "runtime",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "interaction_id",
            "in": "path",
            "required": true,
            "description": "What Bash waits on, by its id: `int_...`, or `call_...` for a call to your tool.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 255
            },
            "description": "Send the same key to retry this call safely for 24 hours."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "type": "string",
                      "const": "interaction",
                      "description": "Always interaction."
                    },
                    "id": {
                      "type": "string",
                      "description": "The interaction, to answer by its id (int_...; call_... for a call to your tool).",
                      "examples": [
                        "int_3j9"
                      ]
                    },
                    "user_id": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Your id for the user it is for; null on your company's own Bash."
                    },
                    "task_id": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The task that asked (task_...); null for a call to your tool that Bash's reply made."
                    },
                    "conversation_id": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Its conversation (conv_...); null when its task has none."
                    },
                    "kind": {
                      "type": "string",
                      "enum": [
                        "ask_question",
                        "composio_auth",
                        "tool_permission",
                        "credit_approval",
                        "exit_plan",
                        "custom",
                        "hands_approval",
                        "plan_limit"
                      ],
                      "description": "What exactly Bash waits on. ask_question: a question, or a hand-off. composio_auth: connecting an app. tool_permission: a step with a tool. credit_approval: spending on a paid tool. exit_plan: a plan before it starts. hands_approval: an action on a computer, approved in person. plan_limit: a plan's limit ran out (read only). custom: anything else, named by details.renderer."
                    },
                    "type": {
                      "type": "string",
                      "enum": [
                        "approval",
                        "question",
                        "connect",
                        "handoff",
                        "tool_call"
                      ],
                      "description": "What kind of answer it takes. approval: yes or no. question: an answer to each question. connect: your user connects an app. handoff: a person does one thing, then says so. tool_call: your tool returns an output or an error."
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "pending",
                        "resolved",
                        "cancelled",
                        "expired"
                      ],
                      "description": "pending: Bash waits on it. resolved: it was answered. cancelled: it was withdrawn before an answer. expired: nobody answered in time."
                    },
                    "summary": {
                      "type": "string",
                      "description": "What Bash wants, in a phrase to show your user.",
                      "examples": [
                        "pay, amount $500.00",
                        "Connect Gmail"
                      ]
                    },
                    "moves_money": {
                      "anyOf": [
                        {
                          "type": "boolean"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Whether saying yes spends money, such as a payment. null on the card for one of your own tools (a function of yours, or a tool of your MCP servers): your app knows what your tools cost, and Vestra cannot."
                    },
                    "requires_present_user": {
                      "type": "boolean",
                      "description": "Whether a yes needs present_user: true, meaning the person who saw it said yes: true for a payment, and for an action approved in person."
                    },
                    "nonce": {
                      "description": "For an action approved in person (hands_approval) only: send it back with your yes.",
                      "type": "string"
                    },
                    "questions": {
                      "description": "For a question or a hand-off: what Bash asks, one or more questions.",
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "question": {
                            "type": "string",
                            "description": "The question, as Bash asks it.",
                            "examples": [
                              "Which flight should I book?"
                            ]
                          },
                          "header": {
                            "type": "string",
                            "description": "A short label for it, for a heading or a chip; empty when Bash gave none."
                          },
                          "options": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "label": {
                                  "type": "string",
                                  "description": "An answer your user can pick."
                                },
                                "description": {
                                  "type": "string",
                                  "description": "A line more about that answer; empty when there is none."
                                }
                              },
                              "required": [
                                "label",
                                "description"
                              ]
                            },
                            "description": "Answers Bash suggests; your user may still answer in their own words. Empty when it suggests none."
                          },
                          "multi_select": {
                            "type": "boolean",
                            "description": "Whether more than one option may be picked."
                          }
                        },
                        "required": [
                          "question",
                          "header",
                          "options",
                          "multi_select"
                        ]
                      }
                    },
                    "frame_url": {
                      "description": "For a hand-off, on a single read only (never in lists): the page Bash was on when it asked, as a JPEG data URI.",
                      "type": "string"
                    },
                    "browser": {
                      "description": "For a hand-off in the browser: open a session with a screen (POST /v1/sessions) so a person can do it.",
                      "type": "object",
                      "properties": {
                        "suggested_mode": {
                          "type": "string",
                          "const": "control",
                          "description": "Open the screen with control, so the person can take the wheel."
                        },
                        "url": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ],
                          "description": "The page Bash's browser is on; null when it did not say."
                        }
                      },
                      "required": [
                        "suggested_mode",
                        "url"
                      ]
                    },
                    "details": {
                      "type": "object",
                      "propertyNames": {
                        "type": "string"
                      },
                      "additionalProperties": {},
                      "description": "A few named facts for its kind, safe to show: such as tool_name and rows for a tool step (with server for a tool of an MCP server, and its arguments as rows), or app for a connection. Never the raw request."
                    },
                    "outcome": {
                      "anyOf": [
                        {
                          "type": "object",
                          "properties": {
                            "decision": {
                              "type": "string",
                              "enum": [
                                "approved",
                                "denied",
                                "answered",
                                "cancelled",
                                "expired"
                              ],
                              "description": "How it ended."
                            },
                            "answers": {
                              "description": "For an answered question: the answer to each question, in order.",
                              "type": "array",
                              "items": {
                                "type": "string"
                              }
                            },
                            "reason": {
                              "description": "For a denial: why, when one was recorded.",
                              "type": "string"
                            },
                            "message": {
                              "description": "For a denial: the note that was sent with the no, when there was one.",
                              "type": "string"
                            }
                          },
                          "required": [
                            "decision"
                          ]
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "How it ended; null while it is pending."
                    },
                    "created_at": {
                      "type": "string",
                      "description": "When Bash asked, as an ISO 8601 time."
                    },
                    "expires_at": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "When it expires unanswered, as an ISO 8601 time; null when it never does."
                    },
                    "resolved_at": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "When it was answered, withdrawn or expired, as an ISO 8601 time; null while pending."
                    }
                  },
                  "required": [
                    "object",
                    "id",
                    "user_id",
                    "task_id",
                    "conversation_id",
                    "kind",
                    "type",
                    "status",
                    "summary",
                    "moves_money",
                    "requires_present_user",
                    "details",
                    "outcome",
                    "created_at",
                    "expires_at",
                    "resolved_at"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "reason": {
                    "default": "Withdrawn by the company.",
                    "description": "Why it was withdrawn, for Bash, in at most 500 characters. Default: Withdrawn by the company.",
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 500
                  }
                },
                "additionalProperties": false
              }
            }
          }
        }
      }
    },
    "/v1/files": {
      "post": {
        "operationId": "postFiles",
        "summary": "Upload a file for Bash to use: multipart/form-data with one part named file. user_id in the query names whose Bash it is for; without it, the company's own.",
        "tags": [
          "Files"
        ],
        "x-vestra-line": "files",
        "x-vestra-scope": "runtime",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "user_id",
            "in": "query",
            "required": false,
            "schema": {
              "description": "Whose file it is, by your id for them. Absent: your company's own Bash's.",
              "type": "string",
              "pattern": "^[A-Za-z0-9][A-Za-z0-9._:@-]{0,127}$",
              "examples": [
                "traveller-42"
              ]
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 255
            },
            "description": "Send the same key to retry this call safely for 24 hours."
          }
        ],
        "responses": {
          "201": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "The file (file_...): hand it to an ask as an attachment.",
                      "examples": [
                        "file_2nq"
                      ]
                    },
                    "object": {
                      "type": "string",
                      "const": "file",
                      "description": "Always file."
                    },
                    "user_id": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Your id for its user; null on your company's own Bash."
                    },
                    "filename": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The file's name; null when it has none.",
                      "examples": [
                        "itinerary.pdf"
                      ]
                    },
                    "mime_type": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Its type, such as application/pdf; null when unknown."
                    },
                    "size_bytes": {
                      "anyOf": [
                        {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Its size, in bytes; null when unknown."
                    },
                    "source": {
                      "type": "string",
                      "enum": [
                        "upload",
                        "output"
                      ],
                      "description": "upload: a file you handed Bash. output: a file Bash made."
                    },
                    "task_id": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The task it belongs to (task_...): the one that made it, or used it; null when none did."
                    },
                    "conversation_id": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The conversation of its task (conv_...); null for a file no task touched."
                    },
                    "created_at": {
                      "type": "string",
                      "description": "When it was made or uploaded, as an ISO 8601 time."
                    }
                  },
                  "required": [
                    "id",
                    "object",
                    "user_id",
                    "filename",
                    "mime_type",
                    "size_bytes",
                    "source",
                    "task_id",
                    "conversation_id",
                    "created_at"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary",
                    "contentEncoding": "binary",
                    "maxLength": 10485760,
                    "description": "The file, in a form field named file: 10 MB at most."
                  }
                },
                "required": [
                  "file"
                ]
              }
            }
          }
        }
      },
      "get": {
        "operationId": "getFiles",
        "summary": "Files, each with its task and conversation: one user's (user_id) or the company's own Bash's, one task's outputs (task_id), or one conversation's, its tasks' outputs (conversation_id). source picks what you handed Bash (upload) or what Bash made (output).",
        "tags": [
          "Files"
        ],
        "x-vestra-line": "files",
        "x-vestra-scope": "runtime",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "default": 20,
              "description": "How many items per page, 1 to 100. Default 20.",
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "description": "Where to go on from: the `next_cursor` of the page before, unchanged. Absent: the first page.",
              "type": "string"
            }
          },
          {
            "name": "user_id",
            "in": "query",
            "required": false,
            "schema": {
              "description": "One user's files, by your id for them. Absent: your company's own Bash's.",
              "type": "string",
              "pattern": "^[A-Za-z0-9][A-Za-z0-9._:@-]{0,127}$",
              "examples": [
                "traveller-42"
              ]
            }
          },
          {
            "name": "task_id",
            "in": "query",
            "required": false,
            "schema": {
              "description": "What one task made (task_...): outputs only.",
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "conversation_id",
            "in": "query",
            "required": false,
            "schema": {
              "description": "One conversation's files, from all its tasks (conv_...).",
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "source",
            "in": "query",
            "required": false,
            "schema": {
              "description": "Only uploads or only outputs. Default: outputs with task_id or conversation_id, uploads without.",
              "type": "string",
              "enum": [
                "upload",
                "output"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "The file (file_...): hand it to an ask as an attachment.",
                            "examples": [
                              "file_2nq"
                            ]
                          },
                          "object": {
                            "type": "string",
                            "const": "file",
                            "description": "Always file."
                          },
                          "user_id": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "Your id for its user; null on your company's own Bash."
                          },
                          "filename": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "The file's name; null when it has none.",
                            "examples": [
                              "itinerary.pdf"
                            ]
                          },
                          "mime_type": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "Its type, such as application/pdf; null when unknown."
                          },
                          "size_bytes": {
                            "anyOf": [
                              {
                                "type": "integer",
                                "minimum": -9007199254740991,
                                "maximum": 9007199254740991
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "Its size, in bytes; null when unknown."
                          },
                          "source": {
                            "type": "string",
                            "enum": [
                              "upload",
                              "output"
                            ],
                            "description": "upload: a file you handed Bash. output: a file Bash made."
                          },
                          "task_id": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "The task it belongs to (task_...): the one that made it, or used it; null when none did."
                          },
                          "conversation_id": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "The conversation of its task (conv_...); null for a file no task touched."
                          },
                          "created_at": {
                            "type": "string",
                            "description": "When it was made or uploaded, as an ISO 8601 time."
                          }
                        },
                        "required": [
                          "id",
                          "object",
                          "user_id",
                          "filename",
                          "mime_type",
                          "size_bytes",
                          "source",
                          "task_id",
                          "conversation_id",
                          "created_at"
                        ]
                      },
                      "description": "The items on this page."
                    },
                    "next_cursor": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Send it as `cursor` for the next page; null on the last page."
                    }
                  },
                  "required": [
                    "data",
                    "next_cursor"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/files/{file_id}": {
      "get": {
        "operationId": "getFilesByFileId",
        "summary": "Details and a short-lived download link.",
        "tags": [
          "Files"
        ],
        "x-vestra-line": "files",
        "x-vestra-scope": "runtime",
        "security": [
          {
            "apiKey": []
          },
          {
            "clientToken": []
          }
        ],
        "parameters": [
          {
            "name": "file_id",
            "in": "path",
            "required": true,
            "description": "The file's id (`file_...`).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "The file (file_...): hand it to an ask as an attachment.",
                      "examples": [
                        "file_2nq"
                      ]
                    },
                    "object": {
                      "type": "string",
                      "const": "file",
                      "description": "Always file."
                    },
                    "user_id": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Your id for its user; null on your company's own Bash."
                    },
                    "filename": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The file's name; null when it has none.",
                      "examples": [
                        "itinerary.pdf"
                      ]
                    },
                    "mime_type": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Its type, such as application/pdf; null when unknown."
                    },
                    "size_bytes": {
                      "anyOf": [
                        {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Its size, in bytes; null when unknown."
                    },
                    "source": {
                      "type": "string",
                      "enum": [
                        "upload",
                        "output"
                      ],
                      "description": "upload: a file you handed Bash. output: a file Bash made."
                    },
                    "task_id": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The task it belongs to (task_...): the one that made it, or used it; null when none did."
                    },
                    "conversation_id": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The conversation of its task (conv_...); null for a file no task touched."
                    },
                    "created_at": {
                      "type": "string",
                      "description": "When it was made or uploaded, as an ISO 8601 time."
                    },
                    "download_url": {
                      "type": "string",
                      "format": "uri",
                      "description": "A link to download it: good for 15 minutes, so read the file again for a fresh one."
                    },
                    "download_expires_at": {
                      "type": "string",
                      "description": "When the link stops working, as an ISO 8601 time."
                    }
                  },
                  "required": [
                    "id",
                    "object",
                    "user_id",
                    "filename",
                    "mime_type",
                    "size_bytes",
                    "source",
                    "task_id",
                    "conversation_id",
                    "created_at",
                    "download_url",
                    "download_expires_at"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteFilesByFileId",
        "summary": "Delete it.",
        "tags": [
          "Files"
        ],
        "x-vestra-line": "files",
        "x-vestra-scope": "runtime",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "file_id",
            "in": "path",
            "required": true,
            "description": "The file's id (`file_...`).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "The file (file_...)."
                    },
                    "object": {
                      "type": "string",
                      "const": "file",
                      "description": "Always file."
                    },
                    "deleted": {
                      "type": "boolean",
                      "const": true,
                      "description": "Always true: it is gone."
                    }
                  },
                  "required": [
                    "id",
                    "object",
                    "deleted"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/apps": {
      "get": {
        "operationId": "getApps",
        "summary": "The apps your users may connect, after your allowlist.",
        "tags": [
          "Connected apps"
        ],
        "x-vestra-line": "connect",
        "x-vestra-scope": "runtime",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "default": 20,
              "description": "How many items per page, 1 to 100. Default 20.",
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "description": "Where to go on from: the `next_cursor` of the page before, unchanged. Absent: the first page.",
              "type": "string"
            }
          },
          {
            "name": "search",
            "in": "query",
            "required": false,
            "schema": {
              "description": "Only apps whose name holds these words.",
              "examples": [
                "calendar"
              ],
              "type": "string",
              "minLength": 1,
              "maxLength": 100
            }
          },
          {
            "name": "category",
            "in": "query",
            "required": false,
            "schema": {
              "description": "Only apps of this category.",
              "type": "string",
              "minLength": 1,
              "maxLength": 100
            }
          },
          {
            "name": "deployment_id",
            "in": "query",
            "required": false,
            "schema": {
              "description": "Only the apps this deployment allows (its `apps`), by its `dep_` id or name. Absent: the company default's.",
              "type": "string",
              "minLength": 1,
              "maxLength": 128
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "object": {
                            "type": "string",
                            "const": "app",
                            "description": "Always `app`."
                          },
                          "slug": {
                            "type": "string",
                            "description": "The app's name in calls: what `app` takes when you connect it.",
                            "examples": [
                              "gmail"
                            ]
                          },
                          "name": {
                            "type": "string",
                            "description": "The app's name, as people read it.",
                            "examples": [
                              "Gmail"
                            ]
                          },
                          "description": {
                            "type": "string",
                            "description": "What the app is, in a line."
                          },
                          "category": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "What kind of app it is, such as `email`; null when it has none."
                          },
                          "logo_url": {
                            "type": "string",
                            "description": "The app's logo, an image URL."
                          },
                          "connectable": {
                            "type": "boolean",
                            "description": "false when Vestra cannot connect it yet."
                          },
                          "no_auth": {
                            "type": "boolean",
                            "description": "true when it needs no sign-in: its tools just run."
                          }
                        },
                        "required": [
                          "object",
                          "slug",
                          "name",
                          "description",
                          "category",
                          "logo_url",
                          "connectable",
                          "no_auth"
                        ]
                      },
                      "description": "The items on this page."
                    },
                    "next_cursor": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Send it as `cursor` for the next page; null on the last page."
                    }
                  },
                  "required": [
                    "data",
                    "next_cursor"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/connections": {
      "post": {
        "operationId": "postConnections",
        "summary": "Get a connect link for one app, for one user (user_id) or the company's own Bash. After consent the user lands on your return_url (or your first allowed one, or our own page), and a webhook fires. The link carries the id of the connection it makes.",
        "tags": [
          "Connected apps"
        ],
        "x-vestra-line": "connect",
        "x-vestra-scope": "runtime",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 255
            },
            "description": "Send the same key to retry this call safely for 24 hours."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "type": "string",
                      "const": "connect_link",
                      "description": "Always `connect_link`."
                    },
                    "id": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The connection this link makes (`con_`), to read with GET /v1/connections/{connection_id}; null only when there is none to make (an app with no sign-in)."
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "pending",
                        "connected"
                      ],
                      "description": "`pending`: send the user to `url`. `connected`: they already had this app, or it needs no sign-in."
                    },
                    "url": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The sign-in link: send it to your user, or open it yourself for your company's own Bash. Null when there is nothing to sign in to."
                    },
                    "connection": {
                      "anyOf": [
                        {
                          "type": "object",
                          "properties": {
                            "object": {
                              "type": "string",
                              "const": "connection",
                              "description": "Always `connection`."
                            },
                            "id": {
                              "type": "string",
                              "description": "The connection's id.",
                              "examples": [
                                "con_8f2k"
                              ]
                            },
                            "user_id": {
                              "anyOf": [
                                {
                                  "type": "string"
                                },
                                {
                                  "type": "null"
                                }
                              ],
                              "description": "Your id for the user; null for your company's own Bash."
                            },
                            "app": {
                              "type": "string",
                              "description": "The app, by its slug.",
                              "examples": [
                                "gmail"
                              ]
                            },
                            "status": {
                              "type": "string",
                              "enum": [
                                "active",
                                "pending",
                                "initializing",
                                "expired",
                                "revoked",
                                "inactive",
                                "failed"
                              ],
                              "description": "`active`: Bash can use it. `pending` or `initializing`: the sign-in is not finished. `expired`, `revoked`, `inactive` or `failed`: it no longer works, and the user connects it again."
                            },
                            "label": {
                              "anyOf": [
                                {
                                  "type": "string"
                                },
                                {
                                  "type": "null"
                                }
                              ],
                              "description": "The account's label, usually its email; null when the app gives none."
                            },
                            "created_at": {
                              "type": "string",
                              "description": "When it was connected, as an ISO 8601 date and time in UTC."
                            }
                          },
                          "required": [
                            "object",
                            "id",
                            "user_id",
                            "app",
                            "status",
                            "label",
                            "created_at"
                          ]
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The connection when it is already made; null while it is pending."
                    },
                    "expires_at": {
                      "type": "string",
                      "description": "When the link stops working, as an ISO 8601 date and time in UTC."
                    }
                  },
                  "required": [
                    "object",
                    "id",
                    "status",
                    "url",
                    "connection",
                    "expires_at"
                  ]
                }
              }
            }
          },
          "201": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "type": "string",
                      "const": "connect_link",
                      "description": "Always `connect_link`."
                    },
                    "id": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The connection this link makes (`con_`), to read with GET /v1/connections/{connection_id}; null only when there is none to make (an app with no sign-in)."
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "pending",
                        "connected"
                      ],
                      "description": "`pending`: send the user to `url`. `connected`: they already had this app, or it needs no sign-in."
                    },
                    "url": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The sign-in link: send it to your user, or open it yourself for your company's own Bash. Null when there is nothing to sign in to."
                    },
                    "connection": {
                      "anyOf": [
                        {
                          "type": "object",
                          "properties": {
                            "object": {
                              "type": "string",
                              "const": "connection",
                              "description": "Always `connection`."
                            },
                            "id": {
                              "type": "string",
                              "description": "The connection's id.",
                              "examples": [
                                "con_8f2k"
                              ]
                            },
                            "user_id": {
                              "anyOf": [
                                {
                                  "type": "string"
                                },
                                {
                                  "type": "null"
                                }
                              ],
                              "description": "Your id for the user; null for your company's own Bash."
                            },
                            "app": {
                              "type": "string",
                              "description": "The app, by its slug.",
                              "examples": [
                                "gmail"
                              ]
                            },
                            "status": {
                              "type": "string",
                              "enum": [
                                "active",
                                "pending",
                                "initializing",
                                "expired",
                                "revoked",
                                "inactive",
                                "failed"
                              ],
                              "description": "`active`: Bash can use it. `pending` or `initializing`: the sign-in is not finished. `expired`, `revoked`, `inactive` or `failed`: it no longer works, and the user connects it again."
                            },
                            "label": {
                              "anyOf": [
                                {
                                  "type": "string"
                                },
                                {
                                  "type": "null"
                                }
                              ],
                              "description": "The account's label, usually its email; null when the app gives none."
                            },
                            "created_at": {
                              "type": "string",
                              "description": "When it was connected, as an ISO 8601 date and time in UTC."
                            }
                          },
                          "required": [
                            "object",
                            "id",
                            "user_id",
                            "app",
                            "status",
                            "label",
                            "created_at"
                          ]
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The connection when it is already made; null while it is pending."
                    },
                    "expires_at": {
                      "type": "string",
                      "description": "When the link stops working, as an ISO 8601 date and time in UTC."
                    }
                  },
                  "required": [
                    "object",
                    "id",
                    "status",
                    "url",
                    "connection",
                    "expires_at"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "user_id": {
                    "description": "Whose Bash: your id for the user. Absent: your company's own Bash.",
                    "examples": [
                      "traveller-42"
                    ],
                    "type": "string",
                    "pattern": "^[A-Za-z0-9][A-Za-z0-9._:@-]{0,127}$"
                  },
                  "app": {
                    "type": "string",
                    "pattern": "^[a-z0-9][a-z0-9_-]{0,63}$",
                    "description": "The app to connect, by its slug from GET /v1/apps.",
                    "examples": [
                      "gmail"
                    ]
                  },
                  "return_url": {
                    "description": "Where the user lands after they sign in; it must match one of your allowed return URLs. Absent: your first allowed return URL, or our own page.",
                    "examples": [
                      "https://app.example.com/connected"
                    ],
                    "type": "string",
                    "maxLength": 2048,
                    "format": "uri"
                  },
                  "deployment_id": {
                    "description": "The deployment whose `apps` decide whether this app is allowed, by its `dep_` id or name. Absent: the company default's.",
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 128
                  }
                },
                "required": [
                  "app"
                ],
                "additionalProperties": false
              }
            }
          }
        }
      },
      "get": {
        "operationId": "getConnections",
        "summary": "The connected apps of one user (user_id), or of the company's own Bash.",
        "tags": [
          "Connected apps"
        ],
        "x-vestra-line": "connect",
        "x-vestra-scope": "runtime",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "default": 20,
              "description": "How many items per page, 1 to 100. Default 20.",
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "description": "Where to go on from: the `next_cursor` of the page before, unchanged. Absent: the first page.",
              "type": "string"
            }
          },
          {
            "name": "user_id",
            "in": "query",
            "required": false,
            "schema": {
              "description": "Whose Bash: your id for the user. Absent: your company's own Bash.",
              "examples": [
                "traveller-42"
              ],
              "type": "string",
              "pattern": "^[A-Za-z0-9][A-Za-z0-9._:@-]{0,127}$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "object": {
                            "type": "string",
                            "const": "connection",
                            "description": "Always `connection`."
                          },
                          "id": {
                            "type": "string",
                            "description": "The connection's id.",
                            "examples": [
                              "con_8f2k"
                            ]
                          },
                          "user_id": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "Your id for the user; null for your company's own Bash."
                          },
                          "app": {
                            "type": "string",
                            "description": "The app, by its slug.",
                            "examples": [
                              "gmail"
                            ]
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "active",
                              "pending",
                              "initializing",
                              "expired",
                              "revoked",
                              "inactive",
                              "failed"
                            ],
                            "description": "`active`: Bash can use it. `pending` or `initializing`: the sign-in is not finished. `expired`, `revoked`, `inactive` or `failed`: it no longer works, and the user connects it again."
                          },
                          "label": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "The account's label, usually its email; null when the app gives none."
                          },
                          "created_at": {
                            "type": "string",
                            "description": "When it was connected, as an ISO 8601 date and time in UTC."
                          }
                        },
                        "required": [
                          "object",
                          "id",
                          "user_id",
                          "app",
                          "status",
                          "label",
                          "created_at"
                        ]
                      },
                      "description": "The items on this page."
                    },
                    "next_cursor": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Send it as `cursor` for the next page; null on the last page."
                    }
                  },
                  "required": [
                    "data",
                    "next_cursor"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/connections/{connection_id}": {
      "get": {
        "operationId": "getConnectionsByConnectionId",
        "summary": "One connection's status. user_id names whose it is.",
        "tags": [
          "Connected apps"
        ],
        "x-vestra-line": "connect",
        "x-vestra-scope": "runtime",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "connection_id",
            "in": "path",
            "required": true,
            "description": "The connected app's id (`con_...`).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "user_id",
            "in": "query",
            "required": false,
            "schema": {
              "description": "Whose Bash: your id for the user. Absent: your company's own Bash.",
              "examples": [
                "traveller-42"
              ],
              "type": "string",
              "pattern": "^[A-Za-z0-9][A-Za-z0-9._:@-]{0,127}$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "type": "string",
                      "const": "connection",
                      "description": "Always `connection`."
                    },
                    "id": {
                      "type": "string",
                      "description": "The connection's id.",
                      "examples": [
                        "con_8f2k"
                      ]
                    },
                    "user_id": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Your id for the user; null for your company's own Bash."
                    },
                    "app": {
                      "type": "string",
                      "description": "The app, by its slug.",
                      "examples": [
                        "gmail"
                      ]
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "active",
                        "pending",
                        "initializing",
                        "expired",
                        "revoked",
                        "inactive",
                        "failed"
                      ],
                      "description": "`active`: Bash can use it. `pending` or `initializing`: the sign-in is not finished. `expired`, `revoked`, `inactive` or `failed`: it no longer works, and the user connects it again."
                    },
                    "label": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The account's label, usually its email; null when the app gives none."
                    },
                    "created_at": {
                      "type": "string",
                      "description": "When it was connected, as an ISO 8601 date and time in UTC."
                    }
                  },
                  "required": [
                    "object",
                    "id",
                    "user_id",
                    "app",
                    "status",
                    "label",
                    "created_at"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteConnectionsByConnectionId",
        "summary": "Disconnect. user_id names whose it is.",
        "tags": [
          "Connected apps"
        ],
        "x-vestra-line": "connect",
        "x-vestra-scope": "runtime",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "connection_id",
            "in": "path",
            "required": true,
            "description": "The connected app's id (`con_...`).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "user_id",
            "in": "query",
            "required": false,
            "schema": {
              "description": "Whose Bash: your id for the user. Absent: your company's own Bash.",
              "examples": [
                "traveller-42"
              ],
              "type": "string",
              "pattern": "^[A-Za-z0-9][A-Za-z0-9._:@-]{0,127}$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "type": "string",
                      "const": "connection",
                      "description": "Always `connection`."
                    },
                    "id": {
                      "type": "string",
                      "description": "The disconnected connection's id."
                    },
                    "deleted": {
                      "type": "boolean",
                      "const": true,
                      "description": "Always true: Bash can no longer use the app for this user."
                    }
                  },
                  "required": [
                    "object",
                    "id",
                    "deleted"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/connect/return": {
      "get": {
        "operationId": "getConnectReturn",
        "summary": "Hosted by us. The app sends the user here after consent; we record it and forward them to your return_url. You never call it.",
        "tags": [
          "Connected apps"
        ],
        "x-vestra-line": "connect",
        "security": [],
        "parameters": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/mcp-servers": {
      "get": {
        "operationId": "getMcpServers",
        "summary": "Your registered MCP servers.",
        "tags": [
          "MCP servers and secrets"
        ],
        "x-vestra-line": "deploy",
        "x-vestra-scope": "setup",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "default": 20,
              "description": "How many items per page, 1 to 100. Default 20.",
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "description": "Where to go on from: the `next_cursor` of the page before, unchanged. Absent: the first page.",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "object": {
                            "type": "string",
                            "const": "mcp_server",
                            "description": "Always `mcp_server`."
                          },
                          "id": {
                            "type": "string",
                            "description": "The MCP server's id.",
                            "examples": [
                              "mcp_8f2k"
                            ]
                          },
                          "slug": {
                            "type": "string",
                            "description": "The name Bash calls it by."
                          },
                          "name": {
                            "type": "string",
                            "description": "Its name, as people read it."
                          },
                          "url": {
                            "type": "string",
                            "description": "The server's https URL."
                          },
                          "auth": {
                            "type": "object",
                            "properties": {
                              "type": {
                                "type": "string",
                                "enum": [
                                  "none",
                                  "headers"
                                ],
                                "description": "`none`, or `headers` sent with every call."
                              },
                              "headers": {
                                "description": "The headers, as written: a credential shows as its `${secret:NAME}`, never its value.",
                                "type": "object",
                                "propertyNames": {
                                  "type": "string"
                                },
                                "additionalProperties": {
                                  "type": "string"
                                }
                              }
                            },
                            "required": [
                              "type"
                            ],
                            "description": "How Bash signs in to it."
                          },
                          "tools": {
                            "type": "object",
                            "properties": {
                              "deny": {
                                "type": "array",
                                "items": {
                                  "type": "string"
                                },
                                "description": "Tools of the server Bash never calls, by name, at most 200. Every deployment that names the server runs under it."
                              },
                              "require_approval": {
                                "type": "array",
                                "items": {
                                  "type": "string"
                                },
                                "description": "Tools of the server that always wait for the person's yes, by name, at most 200."
                              }
                            },
                            "required": [
                              "deny",
                              "require_approval"
                            ],
                            "description": "Which of its tools Bash never calls (`deny`), and which wait for the person's yes (`require_approval`), in every deployment that uses the server. A deployment may add to either list, never take from it."
                          },
                          "secrets": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            },
                            "description": "The company secrets it needs (`${secret:NAME}`), by name: store each with PUT /v1/secrets/{name}."
                          },
                          "user_secrets": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            },
                            "description": "The secrets each user needs (`${user_secret:NAME}`), by name: store each user's with PUT /v1/secrets/{name} and their `user_id`."
                          },
                          "created_at": {
                            "type": "string",
                            "description": "When it was made, as an ISO 8601 date and time in UTC."
                          },
                          "updated_at": {
                            "type": "string",
                            "description": "When it last changed, as an ISO 8601 date and time in UTC."
                          }
                        },
                        "required": [
                          "object",
                          "id",
                          "slug",
                          "name",
                          "url",
                          "auth",
                          "tools",
                          "secrets",
                          "user_secrets",
                          "created_at",
                          "updated_at"
                        ]
                      },
                      "description": "The items on this page."
                    },
                    "next_cursor": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Send it as `cursor` for the next page; null on the last page."
                    }
                  },
                  "required": [
                    "data",
                    "next_cursor"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "postMcpServers",
        "summary": "Register one: URL, auth (none, or headers using ${secret:NAME} or ${user_secret:NAME}), and its tool policy floor: tools never run and tools that always need approval, for every deployment in both modes. A deployment version's own tool policy adds to the floor and never removes from it.",
        "tags": [
          "MCP servers and secrets"
        ],
        "x-vestra-line": "deploy",
        "x-vestra-scope": "setup",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 255
            },
            "description": "Send the same key to retry this call safely for 24 hours."
          }
        ],
        "responses": {
          "201": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "type": "string",
                      "const": "mcp_server",
                      "description": "Always `mcp_server`."
                    },
                    "id": {
                      "type": "string",
                      "description": "The MCP server's id.",
                      "examples": [
                        "mcp_8f2k"
                      ]
                    },
                    "slug": {
                      "type": "string",
                      "description": "The name Bash calls it by."
                    },
                    "name": {
                      "type": "string",
                      "description": "Its name, as people read it."
                    },
                    "url": {
                      "type": "string",
                      "description": "The server's https URL."
                    },
                    "auth": {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "enum": [
                            "none",
                            "headers"
                          ],
                          "description": "`none`, or `headers` sent with every call."
                        },
                        "headers": {
                          "description": "The headers, as written: a credential shows as its `${secret:NAME}`, never its value.",
                          "type": "object",
                          "propertyNames": {
                            "type": "string"
                          },
                          "additionalProperties": {
                            "type": "string"
                          }
                        }
                      },
                      "required": [
                        "type"
                      ],
                      "description": "How Bash signs in to it."
                    },
                    "tools": {
                      "type": "object",
                      "properties": {
                        "deny": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Tools of the server Bash never calls, by name, at most 200. Every deployment that names the server runs under it."
                        },
                        "require_approval": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Tools of the server that always wait for the person's yes, by name, at most 200."
                        }
                      },
                      "required": [
                        "deny",
                        "require_approval"
                      ],
                      "description": "Which of its tools Bash never calls (`deny`), and which wait for the person's yes (`require_approval`), in every deployment that uses the server. A deployment may add to either list, never take from it."
                    },
                    "secrets": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "The company secrets it needs (`${secret:NAME}`), by name: store each with PUT /v1/secrets/{name}."
                    },
                    "user_secrets": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "The secrets each user needs (`${user_secret:NAME}`), by name: store each user's with PUT /v1/secrets/{name} and their `user_id`."
                    },
                    "created_at": {
                      "type": "string",
                      "description": "When it was made, as an ISO 8601 date and time in UTC."
                    },
                    "updated_at": {
                      "type": "string",
                      "description": "When it last changed, as an ISO 8601 date and time in UTC."
                    }
                  },
                  "required": [
                    "object",
                    "id",
                    "slug",
                    "name",
                    "url",
                    "auth",
                    "tools",
                    "secrets",
                    "user_secrets",
                    "created_at",
                    "updated_at"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 80,
                    "description": "Its name, as people read it, 1 to 80 characters.",
                    "examples": [
                      "Travel desk"
                    ]
                  },
                  "slug": {
                    "type": "string",
                    "pattern": "^[a-z][a-z0-9-]{0,39}$",
                    "description": "The name Bash calls it by: lowercase letters, digits and hyphens, starting with a letter, up to 40.",
                    "examples": [
                      "travel-desk"
                    ]
                  },
                  "url": {
                    "type": "string",
                    "maxLength": 2048,
                    "format": "uri",
                    "description": "The server's public https URL, up to 2,048 characters.",
                    "examples": [
                      "https://mcp.example.com/travel"
                    ]
                  },
                  "auth": {
                    "default": {
                      "type": "none"
                    },
                    "description": "How Bash signs in to it. Default `{ \"type\": \"none\" }`.",
                    "oneOf": [
                      {
                        "type": "object",
                        "properties": {
                          "type": {
                            "type": "string",
                            "const": "none",
                            "description": "`none`: the server needs no credentials."
                          }
                        },
                        "required": [
                          "type"
                        ]
                      },
                      {
                        "type": "object",
                        "properties": {
                          "type": {
                            "type": "string",
                            "const": "headers",
                            "description": "`headers`: sent with every call to the server."
                          },
                          "headers": {
                            "type": "object",
                            "propertyNames": {
                              "type": "string",
                              "pattern": "^[A-Za-z0-9-]{1,64}$"
                            },
                            "additionalProperties": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 2048
                            },
                            "description": "Header names to values. A credential is `${secret:NAME}` (your company's) or `${user_secret:NAME}` (each user's own), never the raw value.",
                            "examples": [
                              {
                                "Authorization": "Bearer ${secret:TRAVEL_MCP_TOKEN}"
                              }
                            ]
                          }
                        },
                        "required": [
                          "type",
                          "headers"
                        ]
                      },
                      {
                        "type": "object",
                        "properties": {
                          "type": {
                            "type": "string",
                            "const": "oauth",
                            "description": "`oauth`: not available yet; it answers 400 `oauth_not_available`."
                          }
                        },
                        "required": [
                          "type"
                        ]
                      }
                    ]
                  },
                  "tools": {
                    "default": {
                      "deny": [],
                      "require_approval": []
                    },
                    "description": "Which of its tools Bash never calls (`deny`), and which wait for the person's yes (`require_approval`), in every deployment that uses the server. A deployment may add to either list, never take from it. Default: no rule.",
                    "type": "object",
                    "properties": {
                      "deny": {
                        "default": [],
                        "description": "Tools of the server Bash never calls, by name, at most 200. Every deployment that names the server runs under it.",
                        "maxItems": 200,
                        "type": "array",
                        "items": {
                          "type": "string",
                          "pattern": "^[A-Za-z0-9_.-]{1,128}$"
                        }
                      },
                      "require_approval": {
                        "default": [],
                        "description": "Tools of the server that always wait for the person's yes, by name, at most 200.",
                        "maxItems": 200,
                        "type": "array",
                        "items": {
                          "type": "string",
                          "pattern": "^[A-Za-z0-9_.-]{1,128}$"
                        }
                      }
                    },
                    "additionalProperties": false
                  }
                },
                "required": [
                  "name",
                  "slug",
                  "url"
                ],
                "additionalProperties": false
              }
            }
          }
        }
      }
    },
    "/v1/mcp-servers/{server_id}": {
      "get": {
        "operationId": "getMcpServersByServerId",
        "summary": "One server and its settings.",
        "tags": [
          "MCP servers and secrets"
        ],
        "x-vestra-line": "deploy",
        "x-vestra-scope": "setup",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "server_id",
            "in": "path",
            "required": true,
            "description": "The MCP server's id (`mcp_...`).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "type": "string",
                      "const": "mcp_server",
                      "description": "Always `mcp_server`."
                    },
                    "id": {
                      "type": "string",
                      "description": "The MCP server's id.",
                      "examples": [
                        "mcp_8f2k"
                      ]
                    },
                    "slug": {
                      "type": "string",
                      "description": "The name Bash calls it by."
                    },
                    "name": {
                      "type": "string",
                      "description": "Its name, as people read it."
                    },
                    "url": {
                      "type": "string",
                      "description": "The server's https URL."
                    },
                    "auth": {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "enum": [
                            "none",
                            "headers"
                          ],
                          "description": "`none`, or `headers` sent with every call."
                        },
                        "headers": {
                          "description": "The headers, as written: a credential shows as its `${secret:NAME}`, never its value.",
                          "type": "object",
                          "propertyNames": {
                            "type": "string"
                          },
                          "additionalProperties": {
                            "type": "string"
                          }
                        }
                      },
                      "required": [
                        "type"
                      ],
                      "description": "How Bash signs in to it."
                    },
                    "tools": {
                      "type": "object",
                      "properties": {
                        "deny": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Tools of the server Bash never calls, by name, at most 200. Every deployment that names the server runs under it."
                        },
                        "require_approval": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Tools of the server that always wait for the person's yes, by name, at most 200."
                        }
                      },
                      "required": [
                        "deny",
                        "require_approval"
                      ],
                      "description": "Which of its tools Bash never calls (`deny`), and which wait for the person's yes (`require_approval`), in every deployment that uses the server. A deployment may add to either list, never take from it."
                    },
                    "secrets": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "The company secrets it needs (`${secret:NAME}`), by name: store each with PUT /v1/secrets/{name}."
                    },
                    "user_secrets": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "The secrets each user needs (`${user_secret:NAME}`), by name: store each user's with PUT /v1/secrets/{name} and their `user_id`."
                    },
                    "created_at": {
                      "type": "string",
                      "description": "When it was made, as an ISO 8601 date and time in UTC."
                    },
                    "updated_at": {
                      "type": "string",
                      "description": "When it last changed, as an ISO 8601 date and time in UTC."
                    }
                  },
                  "required": [
                    "object",
                    "id",
                    "slug",
                    "name",
                    "url",
                    "auth",
                    "tools",
                    "secrets",
                    "user_secrets",
                    "created_at",
                    "updated_at"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "patchMcpServersByServerId",
        "summary": "Change URL, auth or the tool policy floor, for every deployment in both modes. Users pick it up at their next task. While a deployment's live version uses the server, a test key's change answers 409 mcp_server_live: change it with a live key, or as an owner or admin.",
        "tags": [
          "MCP servers and secrets"
        ],
        "x-vestra-line": "deploy",
        "x-vestra-scope": "setup",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "server_id",
            "in": "path",
            "required": true,
            "description": "The MCP server's id (`mcp_...`).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "type": "string",
                      "const": "mcp_server",
                      "description": "Always `mcp_server`."
                    },
                    "id": {
                      "type": "string",
                      "description": "The MCP server's id.",
                      "examples": [
                        "mcp_8f2k"
                      ]
                    },
                    "slug": {
                      "type": "string",
                      "description": "The name Bash calls it by."
                    },
                    "name": {
                      "type": "string",
                      "description": "Its name, as people read it."
                    },
                    "url": {
                      "type": "string",
                      "description": "The server's https URL."
                    },
                    "auth": {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "enum": [
                            "none",
                            "headers"
                          ],
                          "description": "`none`, or `headers` sent with every call."
                        },
                        "headers": {
                          "description": "The headers, as written: a credential shows as its `${secret:NAME}`, never its value.",
                          "type": "object",
                          "propertyNames": {
                            "type": "string"
                          },
                          "additionalProperties": {
                            "type": "string"
                          }
                        }
                      },
                      "required": [
                        "type"
                      ],
                      "description": "How Bash signs in to it."
                    },
                    "tools": {
                      "type": "object",
                      "properties": {
                        "deny": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Tools of the server Bash never calls, by name, at most 200. Every deployment that names the server runs under it."
                        },
                        "require_approval": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Tools of the server that always wait for the person's yes, by name, at most 200."
                        }
                      },
                      "required": [
                        "deny",
                        "require_approval"
                      ],
                      "description": "Which of its tools Bash never calls (`deny`), and which wait for the person's yes (`require_approval`), in every deployment that uses the server. A deployment may add to either list, never take from it."
                    },
                    "secrets": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "The company secrets it needs (`${secret:NAME}`), by name: store each with PUT /v1/secrets/{name}."
                    },
                    "user_secrets": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "The secrets each user needs (`${user_secret:NAME}`), by name: store each user's with PUT /v1/secrets/{name} and their `user_id`."
                    },
                    "created_at": {
                      "type": "string",
                      "description": "When it was made, as an ISO 8601 date and time in UTC."
                    },
                    "updated_at": {
                      "type": "string",
                      "description": "When it last changed, as an ISO 8601 date and time in UTC."
                    }
                  },
                  "required": [
                    "object",
                    "id",
                    "slug",
                    "name",
                    "url",
                    "auth",
                    "tools",
                    "secrets",
                    "user_secrets",
                    "created_at",
                    "updated_at"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "description": "A new name, 1 to 80 characters.",
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 80
                  },
                  "url": {
                    "description": "A new public https URL.",
                    "type": "string",
                    "maxLength": 2048,
                    "format": "uri"
                  },
                  "auth": {
                    "description": "How Bash signs in to it, from now on.",
                    "oneOf": [
                      {
                        "type": "object",
                        "properties": {
                          "type": {
                            "type": "string",
                            "const": "none",
                            "description": "`none`: the server needs no credentials."
                          }
                        },
                        "required": [
                          "type"
                        ]
                      },
                      {
                        "type": "object",
                        "properties": {
                          "type": {
                            "type": "string",
                            "const": "headers",
                            "description": "`headers`: sent with every call to the server."
                          },
                          "headers": {
                            "type": "object",
                            "propertyNames": {
                              "type": "string",
                              "pattern": "^[A-Za-z0-9-]{1,64}$"
                            },
                            "additionalProperties": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 2048
                            },
                            "description": "Header names to values. A credential is `${secret:NAME}` (your company's) or `${user_secret:NAME}` (each user's own), never the raw value.",
                            "examples": [
                              {
                                "Authorization": "Bearer ${secret:TRAVEL_MCP_TOKEN}"
                              }
                            ]
                          }
                        },
                        "required": [
                          "type",
                          "headers"
                        ]
                      },
                      {
                        "type": "object",
                        "properties": {
                          "type": {
                            "type": "string",
                            "const": "oauth",
                            "description": "`oauth`: not available yet; it answers 400 `oauth_not_available`."
                          }
                        },
                        "required": [
                          "type"
                        ]
                      }
                    ]
                  },
                  "tools": {
                    "description": "New rules for its tools (`deny`, `require_approval`), for every deployment that uses the server; a list left out stays as it is.",
                    "type": "object",
                    "properties": {
                      "deny": {
                        "description": "Tools of the server Bash never calls, by name, at most 200. Every deployment that names the server runs under it. It replaces the list; left out, the list stays.",
                        "maxItems": 200,
                        "type": "array",
                        "items": {
                          "type": "string",
                          "pattern": "^[A-Za-z0-9_.-]{1,128}$"
                        }
                      },
                      "require_approval": {
                        "description": "Tools of the server that always wait for the person's yes, by name, at most 200. It replaces the list; left out, the list stays.",
                        "maxItems": 200,
                        "type": "array",
                        "items": {
                          "type": "string",
                          "pattern": "^[A-Za-z0-9_.-]{1,128}$"
                        }
                      }
                    },
                    "additionalProperties": false
                  }
                },
                "additionalProperties": false
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteMcpServersByServerId",
        "summary": "Remove it from every user. While a deployment's live version uses it, a test key answers 409 mcp_server_live.",
        "tags": [
          "MCP servers and secrets"
        ],
        "x-vestra-line": "deploy",
        "x-vestra-scope": "setup",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "server_id",
            "in": "path",
            "required": true,
            "description": "The MCP server's id (`mcp_...`).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "type": "string",
                      "const": "mcp_server",
                      "description": "Always `mcp_server`."
                    },
                    "id": {
                      "type": "string",
                      "description": "The MCP server's id.",
                      "examples": [
                        "mcp_8f2k"
                      ]
                    },
                    "deleted": {
                      "type": "boolean",
                      "const": true,
                      "description": "Always true: it is gone."
                    }
                  },
                  "required": [
                    "object",
                    "id",
                    "deleted"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/mcp-servers/{server_id}/check": {
      "post": {
        "operationId": "postMcpServersByServerIdCheck",
        "summary": "Connect now and list its tools, to prove it works.",
        "tags": [
          "MCP servers and secrets"
        ],
        "x-vestra-line": "deploy",
        "x-vestra-scope": "setup",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "server_id",
            "in": "path",
            "required": true,
            "description": "The MCP server's id (`mcp_...`).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "type": "string",
                      "const": "mcp_check",
                      "description": "Always `mcp_check`."
                    },
                    "ok": {
                      "type": "boolean",
                      "description": "Whether Bash reached the server and listed its tools."
                    },
                    "tools": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "The tools it offers, by name; empty when it could not be reached."
                    },
                    "reason": {
                      "description": "Why not, when `ok` is false: `missing_secret` (see `missing`), `auth_required` (it asked for credentials), `url_not_public`, or `unreachable`.",
                      "type": "string",
                      "enum": [
                        "missing_secret",
                        "auth_required",
                        "url_not_public",
                        "unreachable"
                      ]
                    },
                    "missing": {
                      "description": "With `missing_secret`, the secrets to store first, by name.",
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  },
                  "required": [
                    "object",
                    "ok",
                    "tools"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "user_id": {
                    "description": "Your id for a user, to fill in their `${user_secret:NAME}` headers. Absent: the company's own secrets only.",
                    "examples": [
                      "traveller-42"
                    ],
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 256
                  }
                },
                "additionalProperties": false
              }
            }
          }
        }
      }
    },
    "/v1/mcp-servers/{server_id}/tools": {
      "get": {
        "operationId": "getMcpServersByServerIdTools",
        "summary": "The tools we found, each with its setting in the server's tool policy floor. A deployment version's own policy can add to it.",
        "tags": [
          "MCP servers and secrets"
        ],
        "x-vestra-line": "deploy",
        "x-vestra-scope": "setup",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "server_id",
            "in": "path",
            "required": true,
            "description": "The MCP server's id (`mcp_...`).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "user_id",
            "in": "query",
            "required": false,
            "schema": {
              "description": "Your id for a user, to fill in their `${user_secret:NAME}` headers. Absent: the company's own secrets only.",
              "examples": [
                "traveller-42"
              ],
              "type": "string",
              "minLength": 1,
              "maxLength": 256
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "object": {
                            "type": "string",
                            "const": "mcp_tool",
                            "description": "Always `mcp_tool`."
                          },
                          "name": {
                            "type": "string",
                            "description": "The tool's name, as the server gives it."
                          },
                          "denied": {
                            "type": "boolean",
                            "description": "true when the floor says Bash never calls it."
                          },
                          "requires_approval": {
                            "type": "boolean",
                            "description": "true when the floor says it waits for the person's yes."
                          }
                        },
                        "required": [
                          "object",
                          "name",
                          "denied",
                          "requires_approval"
                        ]
                      },
                      "description": "The items on this page."
                    },
                    "next_cursor": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Send it as `cursor` for the next page; null on the last page."
                    }
                  },
                  "required": [
                    "data",
                    "next_cursor"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/secrets/{name}": {
      "put": {
        "operationId": "putSecretsByName",
        "summary": "Store a secret, write-only: the company's (refer to it as ${secret:NAME}), or with user_id one user's own (${user_secret:NAME}), for example their travel account token. Storing it again replaces it.",
        "tags": [
          "MCP servers and secrets"
        ],
        "x-vestra-line": "secrets",
        "x-vestra-scope": "setup",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "name",
            "in": "path",
            "required": true,
            "description": "The secret's name: capitals, digits and underscores, starting with a capital.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "type": "string",
                      "const": "secret",
                      "description": "Always `secret`."
                    },
                    "name": {
                      "type": "string",
                      "description": "The secret's name.",
                      "examples": [
                        "PNR_API_KEY"
                      ]
                    },
                    "user_id": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Your id for the user whose secret it is; null for your company's."
                    },
                    "mode": {
                      "type": "string",
                      "enum": [
                        "live",
                        "test"
                      ],
                      "description": "The mode it is kept in: a live key reads live secrets, a test key test ones."
                    }
                  },
                  "required": [
                    "object",
                    "name",
                    "user_id",
                    "mode"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "user_id": {
                    "description": "Whose secret: your id for the user, for their own (read as `${user_secret:NAME}`). Absent: your company's (read as `${secret:NAME}`).",
                    "examples": [
                      "traveller-42"
                    ],
                    "type": "string",
                    "pattern": "^[A-Za-z0-9][A-Za-z0-9._:@-]{0,127}$"
                  },
                  "value": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 8192,
                    "description": "The secret itself, up to 8,192 characters. It is write-only: no call ever returns it."
                  }
                },
                "required": [
                  "value"
                ],
                "additionalProperties": false
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteSecretsByName",
        "summary": "Remove one: the company's, or one user's (user_id).",
        "tags": [
          "MCP servers and secrets"
        ],
        "x-vestra-line": "secrets",
        "x-vestra-scope": "setup",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "name",
            "in": "path",
            "required": true,
            "description": "The secret's name: capitals, digits and underscores, starting with a capital.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "user_id",
            "in": "query",
            "required": false,
            "schema": {
              "description": "Whose secret: your id for the user, for their own (read as `${user_secret:NAME}`). Absent: your company's (read as `${secret:NAME}`).",
              "examples": [
                "traveller-42"
              ],
              "type": "string",
              "pattern": "^[A-Za-z0-9][A-Za-z0-9._:@-]{0,127}$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "type": "string",
                      "const": "secret",
                      "description": "Always `secret`."
                    },
                    "name": {
                      "type": "string",
                      "description": "The secret's name.",
                      "examples": [
                        "PNR_API_KEY"
                      ]
                    },
                    "user_id": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Your id for the user whose secret it is; null for your company's."
                    },
                    "deleted": {
                      "type": "boolean",
                      "const": true,
                      "description": "Always true: it is gone."
                    }
                  },
                  "required": [
                    "object",
                    "name",
                    "user_id",
                    "deleted"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/secrets": {
      "get": {
        "operationId": "getSecrets",
        "summary": "Secret names, never the values: the company's, or one user's (user_id).",
        "tags": [
          "MCP servers and secrets"
        ],
        "x-vestra-line": "secrets",
        "x-vestra-scope": "setup",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "default": 20,
              "description": "How many items per page, 1 to 100. Default 20.",
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "description": "Where to go on from: the `next_cursor` of the page before, unchanged. Absent: the first page.",
              "type": "string"
            }
          },
          {
            "name": "user_id",
            "in": "query",
            "required": false,
            "schema": {
              "description": "Whose secret: your id for the user, for their own (read as `${user_secret:NAME}`). Absent: your company's (read as `${secret:NAME}`).",
              "examples": [
                "traveller-42"
              ],
              "type": "string",
              "pattern": "^[A-Za-z0-9][A-Za-z0-9._:@-]{0,127}$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "object": {
                            "type": "string",
                            "const": "secret",
                            "description": "Always `secret`."
                          },
                          "name": {
                            "type": "string",
                            "description": "The secret's name.",
                            "examples": [
                              "PNR_API_KEY"
                            ]
                          },
                          "user_id": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "Your id for the user whose secret it is; null for your company's."
                          },
                          "mode": {
                            "type": "string",
                            "enum": [
                              "live",
                              "test"
                            ],
                            "description": "The mode it is kept in: a live key reads live secrets, a test key test ones."
                          }
                        },
                        "required": [
                          "object",
                          "name",
                          "user_id",
                          "mode"
                        ]
                      },
                      "description": "The items on this page."
                    },
                    "next_cursor": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Send it as `cursor` for the next page; null on the last page."
                    }
                  },
                  "required": [
                    "data",
                    "next_cursor"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/skills": {
      "get": {
        "operationId": "getSkills",
        "summary": "Your company skills, plus the skills Bash already has. A company skill carries sha256, the hash of its files as uploaded, computed the way the SDKs compute a folder's, so an unchanged folder is never uploaded again.",
        "tags": [
          "Skills"
        ],
        "x-vestra-line": "deploy",
        "x-vestra-scope": "setup",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "default": 20,
              "description": "How many items per page, 1 to 100. Default 20.",
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "description": "Where to go on from: the `next_cursor` of the page before, unchanged. Absent: the first page.",
              "type": "string"
            }
          },
          {
            "name": "source",
            "in": "query",
            "required": false,
            "schema": {
              "default": "company",
              "description": "`company` (the default): the skills you uploaded. `built_in`: the skills Bash already has.",
              "type": "string",
              "enum": [
                "company",
                "built_in"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "object": {
                            "type": "string",
                            "const": "skill",
                            "description": "Always `skill`."
                          },
                          "id": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "The skill's id (`skl_`); null for a skill Bash already has."
                          },
                          "source": {
                            "type": "string",
                            "enum": [
                              "company",
                              "built_in"
                            ],
                            "description": "`company`: one you uploaded. `built_in`: one Bash already has."
                          },
                          "slug": {
                            "type": "string",
                            "description": "Its name in a deployment: what `skills` takes for one Bash already has."
                          },
                          "name": {
                            "type": "string",
                            "description": "Its name, from its SKILL.md."
                          },
                          "description": {
                            "type": "string",
                            "description": "What it does, from its SKILL.md: Bash reads this to know when to use it."
                          },
                          "version": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "The current version's content hash; null for a skill Bash already has."
                          },
                          "sha256": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "A hash of the files as uploaded, which the SDKs and the CLI compute over a folder the same way, to upload only a folder that changed. Null for a skill Bash already has, and for one uploaded before this field."
                          },
                          "files": {
                            "description": "Its files, on GET /v1/skills/{skill_id}; absent in lists.",
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "path": {
                                  "type": "string",
                                  "description": "The file's path inside the skill."
                                },
                                "bytes": {
                                  "type": "integer",
                                  "minimum": -9007199254740991,
                                  "maximum": 9007199254740991,
                                  "description": "Its size, in bytes."
                                },
                                "content": {
                                  "type": "string",
                                  "description": "Its text."
                                }
                              },
                              "required": [
                                "path",
                                "bytes",
                                "content"
                              ]
                            }
                          },
                          "created_at": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "When it was uploaded; null for a skill Bash already has."
                          },
                          "updated_at": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "When its newest version was uploaded; null for a skill Bash already has."
                          }
                        },
                        "required": [
                          "object",
                          "id",
                          "source",
                          "slug",
                          "name",
                          "description",
                          "version",
                          "sha256",
                          "created_at",
                          "updated_at"
                        ]
                      },
                      "description": "The items on this page."
                    },
                    "next_cursor": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Send it as `cursor` for the next page; null on the last page."
                    }
                  },
                  "required": [
                    "data",
                    "next_cursor"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "postSkills",
        "summary": "Upload a skill folder as a zip, or as JSON files.",
        "tags": [
          "Skills"
        ],
        "x-vestra-line": "deploy",
        "x-vestra-scope": "setup",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 255
            },
            "description": "Send the same key to retry this call safely for 24 hours."
          }
        ],
        "responses": {
          "201": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "type": "string",
                      "const": "skill",
                      "description": "Always `skill`."
                    },
                    "id": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The skill's id (`skl_`); null for a skill Bash already has."
                    },
                    "source": {
                      "type": "string",
                      "enum": [
                        "company",
                        "built_in"
                      ],
                      "description": "`company`: one you uploaded. `built_in`: one Bash already has."
                    },
                    "slug": {
                      "type": "string",
                      "description": "Its name in a deployment: what `skills` takes for one Bash already has."
                    },
                    "name": {
                      "type": "string",
                      "description": "Its name, from its SKILL.md."
                    },
                    "description": {
                      "type": "string",
                      "description": "What it does, from its SKILL.md: Bash reads this to know when to use it."
                    },
                    "version": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The current version's content hash; null for a skill Bash already has."
                    },
                    "sha256": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "A hash of the files as uploaded, which the SDKs and the CLI compute over a folder the same way, to upload only a folder that changed. Null for a skill Bash already has, and for one uploaded before this field."
                    },
                    "files": {
                      "description": "Its files, on GET /v1/skills/{skill_id}; absent in lists.",
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "path": {
                            "type": "string",
                            "description": "The file's path inside the skill."
                          },
                          "bytes": {
                            "type": "integer",
                            "minimum": -9007199254740991,
                            "maximum": 9007199254740991,
                            "description": "Its size, in bytes."
                          },
                          "content": {
                            "type": "string",
                            "description": "Its text."
                          }
                        },
                        "required": [
                          "path",
                          "bytes",
                          "content"
                        ]
                      }
                    },
                    "created_at": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "When it was uploaded; null for a skill Bash already has."
                    },
                    "updated_at": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "When its newest version was uploaded; null for a skill Bash already has."
                    }
                  },
                  "required": [
                    "object",
                    "id",
                    "source",
                    "slug",
                    "name",
                    "description",
                    "version",
                    "sha256",
                    "created_at",
                    "updated_at"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "files": {
                    "minItems": 1,
                    "maxItems": 200,
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "path": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 200,
                          "description": "The file's path inside the skill, such as `SKILL.md` or `scripts/fill.py`, up to 200 characters."
                        },
                        "content": {
                          "type": "string",
                          "maxLength": 1048576,
                          "description": "The file's text, up to 1 MB."
                        }
                      },
                      "required": [
                        "path",
                        "content"
                      ]
                    },
                    "description": "The skill's files, 1 to 200, with a `SKILL.md` at the top whose frontmatter names it."
                  }
                },
                "required": [
                  "files"
                ],
                "additionalProperties": false
              }
            }
          }
        }
      }
    },
    "/v1/skills/{skill_id}": {
      "get": {
        "operationId": "getSkillsBySkillId",
        "summary": "One skill and its files.",
        "tags": [
          "Skills"
        ],
        "x-vestra-line": "deploy",
        "x-vestra-scope": "setup",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "skill_id",
            "in": "path",
            "required": true,
            "description": "The skill's id (`skl_...`).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "type": "string",
                      "const": "skill",
                      "description": "Always `skill`."
                    },
                    "id": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The skill's id (`skl_`); null for a skill Bash already has."
                    },
                    "source": {
                      "type": "string",
                      "enum": [
                        "company",
                        "built_in"
                      ],
                      "description": "`company`: one you uploaded. `built_in`: one Bash already has."
                    },
                    "slug": {
                      "type": "string",
                      "description": "Its name in a deployment: what `skills` takes for one Bash already has."
                    },
                    "name": {
                      "type": "string",
                      "description": "Its name, from its SKILL.md."
                    },
                    "description": {
                      "type": "string",
                      "description": "What it does, from its SKILL.md: Bash reads this to know when to use it."
                    },
                    "version": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The current version's content hash; null for a skill Bash already has."
                    },
                    "sha256": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "A hash of the files as uploaded, which the SDKs and the CLI compute over a folder the same way, to upload only a folder that changed. Null for a skill Bash already has, and for one uploaded before this field."
                    },
                    "files": {
                      "description": "Its files, on GET /v1/skills/{skill_id}; absent in lists.",
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "path": {
                            "type": "string",
                            "description": "The file's path inside the skill."
                          },
                          "bytes": {
                            "type": "integer",
                            "minimum": -9007199254740991,
                            "maximum": 9007199254740991,
                            "description": "Its size, in bytes."
                          },
                          "content": {
                            "type": "string",
                            "description": "Its text."
                          }
                        },
                        "required": [
                          "path",
                          "bytes",
                          "content"
                        ]
                      }
                    },
                    "created_at": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "When it was uploaded; null for a skill Bash already has."
                    },
                    "updated_at": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "When its newest version was uploaded; null for a skill Bash already has."
                    }
                  },
                  "required": [
                    "object",
                    "id",
                    "source",
                    "slug",
                    "name",
                    "description",
                    "version",
                    "sha256",
                    "created_at",
                    "updated_at"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      },
      "put": {
        "operationId": "putSkillsBySkillId",
        "summary": "Upload a new version.",
        "tags": [
          "Skills"
        ],
        "x-vestra-line": "deploy",
        "x-vestra-scope": "setup",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "skill_id",
            "in": "path",
            "required": true,
            "description": "The skill's id (`skl_...`).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "type": "string",
                      "const": "skill",
                      "description": "Always `skill`."
                    },
                    "id": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The skill's id (`skl_`); null for a skill Bash already has."
                    },
                    "source": {
                      "type": "string",
                      "enum": [
                        "company",
                        "built_in"
                      ],
                      "description": "`company`: one you uploaded. `built_in`: one Bash already has."
                    },
                    "slug": {
                      "type": "string",
                      "description": "Its name in a deployment: what `skills` takes for one Bash already has."
                    },
                    "name": {
                      "type": "string",
                      "description": "Its name, from its SKILL.md."
                    },
                    "description": {
                      "type": "string",
                      "description": "What it does, from its SKILL.md: Bash reads this to know when to use it."
                    },
                    "version": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The current version's content hash; null for a skill Bash already has."
                    },
                    "sha256": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "A hash of the files as uploaded, which the SDKs and the CLI compute over a folder the same way, to upload only a folder that changed. Null for a skill Bash already has, and for one uploaded before this field."
                    },
                    "files": {
                      "description": "Its files, on GET /v1/skills/{skill_id}; absent in lists.",
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "path": {
                            "type": "string",
                            "description": "The file's path inside the skill."
                          },
                          "bytes": {
                            "type": "integer",
                            "minimum": -9007199254740991,
                            "maximum": 9007199254740991,
                            "description": "Its size, in bytes."
                          },
                          "content": {
                            "type": "string",
                            "description": "Its text."
                          }
                        },
                        "required": [
                          "path",
                          "bytes",
                          "content"
                        ]
                      }
                    },
                    "created_at": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "When it was uploaded; null for a skill Bash already has."
                    },
                    "updated_at": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "When its newest version was uploaded; null for a skill Bash already has."
                    }
                  },
                  "required": [
                    "object",
                    "id",
                    "source",
                    "slug",
                    "name",
                    "description",
                    "version",
                    "sha256",
                    "created_at",
                    "updated_at"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "files": {
                    "minItems": 1,
                    "maxItems": 200,
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "path": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 200,
                          "description": "The file's path inside the skill, such as `SKILL.md` or `scripts/fill.py`, up to 200 characters."
                        },
                        "content": {
                          "type": "string",
                          "maxLength": 1048576,
                          "description": "The file's text, up to 1 MB."
                        }
                      },
                      "required": [
                        "path",
                        "content"
                      ]
                    },
                    "description": "The skill's files, 1 to 200, with a `SKILL.md` at the top whose frontmatter names it."
                  }
                },
                "required": [
                  "files"
                ],
                "additionalProperties": false
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteSkillsBySkillId",
        "summary": "Remove it from every user.",
        "tags": [
          "Skills"
        ],
        "x-vestra-line": "deploy",
        "x-vestra-scope": "setup",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "skill_id",
            "in": "path",
            "required": true,
            "description": "The skill's id (`skl_...`).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "type": "string",
                      "const": "skill",
                      "description": "Always `skill`."
                    },
                    "id": {
                      "type": "string",
                      "description": "The deleted skill's id."
                    },
                    "deleted": {
                      "type": "boolean",
                      "const": true,
                      "description": "Always true: it is gone."
                    }
                  },
                  "required": [
                    "object",
                    "id",
                    "deleted"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/skills/{skill_id}/versions": {
      "get": {
        "operationId": "getSkillsBySkillIdVersions",
        "summary": "Every version, each with a content hash.",
        "tags": [
          "Skills"
        ],
        "x-vestra-line": "deploy",
        "x-vestra-scope": "setup",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "skill_id",
            "in": "path",
            "required": true,
            "description": "The skill's id (`skl_...`).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "default": 20,
              "description": "How many items per page, 1 to 100. Default 20.",
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "description": "Where to go on from: the `next_cursor` of the page before, unchanged. Absent: the first page.",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "object": {
                            "type": "string",
                            "const": "skill_version",
                            "description": "Always `skill_version`."
                          },
                          "hash": {
                            "type": "string",
                            "description": "The version's content hash."
                          },
                          "parent_hash": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "The version it replaced; null for the first."
                          },
                          "created_at": {
                            "type": "string",
                            "description": "When it was uploaded, as an ISO 8601 date and time in UTC."
                          }
                        },
                        "required": [
                          "object",
                          "hash",
                          "parent_hash",
                          "created_at"
                        ]
                      },
                      "description": "The items on this page."
                    },
                    "next_cursor": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Send it as `cursor` for the next page; null on the last page."
                    }
                  },
                  "required": [
                    "data",
                    "next_cursor"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/notebooks": {
      "post": {
        "operationId": "postNotebooks",
        "summary": "Create a notebook.",
        "tags": [
          "Notebooks"
        ],
        "x-vestra-line": "deploy",
        "x-vestra-scope": "setup",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 255
            },
            "description": "Send the same key to retry this call safely for 24 hours."
          }
        ],
        "responses": {
          "201": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "type": "string",
                      "const": "notebook",
                      "description": "Always `notebook`."
                    },
                    "id": {
                      "type": "string",
                      "description": "The notebook's id.",
                      "examples": [
                        "nb_8f2k"
                      ]
                    },
                    "slug": {
                      "type": "string",
                      "description": "Its short name."
                    },
                    "name": {
                      "type": "string",
                      "description": "Its name, as people read it."
                    },
                    "description": {
                      "type": "string",
                      "description": "What it holds; empty when none was given."
                    },
                    "access": {
                      "oneOf": [
                        {
                          "type": "object",
                          "properties": {
                            "mode": {
                              "type": "string",
                              "const": "all",
                              "description": "`all`: every user of the company may read it."
                            }
                          },
                          "required": [
                            "mode"
                          ]
                        },
                        {
                          "type": "object",
                          "properties": {
                            "mode": {
                              "type": "string",
                              "const": "named",
                              "description": "`named`: only the users listed may read it."
                            },
                            "user_ids": {
                              "maxItems": 1000,
                              "type": "array",
                              "items": {
                                "type": "string",
                                "minLength": 1,
                                "maxLength": 256
                              },
                              "description": "Your ids for the users who may read it, at most 1,000.",
                              "examples": [
                                [
                                  "traveller-42"
                                ]
                              ]
                            }
                          },
                          "required": [
                            "mode",
                            "user_ids"
                          ]
                        }
                      ],
                      "description": "Who may read it."
                    },
                    "document_count": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991,
                      "description": "How many documents it holds."
                    },
                    "bytes": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991,
                      "description": "The size of its text, in bytes, at most 5 MB."
                    },
                    "created_at": {
                      "type": "string",
                      "description": "When it was made, as an ISO 8601 date and time in UTC."
                    },
                    "updated_at": {
                      "type": "string",
                      "description": "When it last changed, as an ISO 8601 date and time in UTC."
                    }
                  },
                  "required": [
                    "object",
                    "id",
                    "slug",
                    "name",
                    "description",
                    "access",
                    "document_count",
                    "bytes",
                    "created_at",
                    "updated_at"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 80,
                    "description": "Its name, as people read it, 1 to 80 characters.",
                    "examples": [
                      "Refund policy"
                    ]
                  },
                  "slug": {
                    "type": "string",
                    "pattern": "^[a-z][a-z0-9-]{0,39}$",
                    "description": "Its short name: lowercase letters, digits and hyphens, starting with a letter, up to 40.",
                    "examples": [
                      "refund-policy"
                    ]
                  },
                  "description": {
                    "default": "",
                    "description": "What it holds, up to 300 characters: Bash reads this to know when to look in it. Empty by default.",
                    "type": "string",
                    "maxLength": 300
                  },
                  "access": {
                    "default": {
                      "mode": "all"
                    },
                    "description": "Who may read it. Default `{ \"mode\": \"all\" }`.",
                    "oneOf": [
                      {
                        "type": "object",
                        "properties": {
                          "mode": {
                            "type": "string",
                            "const": "all",
                            "description": "`all`: every user of the company may read it."
                          }
                        },
                        "required": [
                          "mode"
                        ]
                      },
                      {
                        "type": "object",
                        "properties": {
                          "mode": {
                            "type": "string",
                            "const": "named",
                            "description": "`named`: only the users listed may read it."
                          },
                          "user_ids": {
                            "maxItems": 1000,
                            "type": "array",
                            "items": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 256
                            },
                            "description": "Your ids for the users who may read it, at most 1,000.",
                            "examples": [
                              [
                                "traveller-42"
                              ]
                            ]
                          }
                        },
                        "required": [
                          "mode",
                          "user_ids"
                        ]
                      }
                    ]
                  }
                },
                "required": [
                  "name",
                  "slug"
                ],
                "additionalProperties": false
              }
            }
          }
        }
      },
      "get": {
        "operationId": "getNotebooks",
        "summary": "Your notebooks.",
        "tags": [
          "Notebooks"
        ],
        "x-vestra-line": "deploy",
        "x-vestra-scope": "setup",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "default": 20,
              "description": "How many items per page, 1 to 100. Default 20.",
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "description": "Where to go on from: the `next_cursor` of the page before, unchanged. Absent: the first page.",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "object": {
                            "type": "string",
                            "const": "notebook",
                            "description": "Always `notebook`."
                          },
                          "id": {
                            "type": "string",
                            "description": "The notebook's id.",
                            "examples": [
                              "nb_8f2k"
                            ]
                          },
                          "slug": {
                            "type": "string",
                            "description": "Its short name."
                          },
                          "name": {
                            "type": "string",
                            "description": "Its name, as people read it."
                          },
                          "description": {
                            "type": "string",
                            "description": "What it holds; empty when none was given."
                          },
                          "access": {
                            "oneOf": [
                              {
                                "type": "object",
                                "properties": {
                                  "mode": {
                                    "type": "string",
                                    "const": "all",
                                    "description": "`all`: every user of the company may read it."
                                  }
                                },
                                "required": [
                                  "mode"
                                ]
                              },
                              {
                                "type": "object",
                                "properties": {
                                  "mode": {
                                    "type": "string",
                                    "const": "named",
                                    "description": "`named`: only the users listed may read it."
                                  },
                                  "user_ids": {
                                    "maxItems": 1000,
                                    "type": "array",
                                    "items": {
                                      "type": "string",
                                      "minLength": 1,
                                      "maxLength": 256
                                    },
                                    "description": "Your ids for the users who may read it, at most 1,000.",
                                    "examples": [
                                      [
                                        "traveller-42"
                                      ]
                                    ]
                                  }
                                },
                                "required": [
                                  "mode",
                                  "user_ids"
                                ]
                              }
                            ],
                            "description": "Who may read it."
                          },
                          "document_count": {
                            "type": "integer",
                            "minimum": -9007199254740991,
                            "maximum": 9007199254740991,
                            "description": "How many documents it holds."
                          },
                          "bytes": {
                            "type": "integer",
                            "minimum": -9007199254740991,
                            "maximum": 9007199254740991,
                            "description": "The size of its text, in bytes, at most 5 MB."
                          },
                          "created_at": {
                            "type": "string",
                            "description": "When it was made, as an ISO 8601 date and time in UTC."
                          },
                          "updated_at": {
                            "type": "string",
                            "description": "When it last changed, as an ISO 8601 date and time in UTC."
                          }
                        },
                        "required": [
                          "object",
                          "id",
                          "slug",
                          "name",
                          "description",
                          "access",
                          "document_count",
                          "bytes",
                          "created_at",
                          "updated_at"
                        ]
                      },
                      "description": "The items on this page."
                    },
                    "next_cursor": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Send it as `cursor` for the next page; null on the last page."
                    }
                  },
                  "required": [
                    "data",
                    "next_cursor"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/notebooks/{notebook_id}": {
      "get": {
        "operationId": "getNotebooksByNotebookId",
        "summary": "One notebook and who may read it.",
        "tags": [
          "Notebooks"
        ],
        "x-vestra-line": "deploy",
        "x-vestra-scope": "setup",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "notebook_id",
            "in": "path",
            "required": true,
            "description": "The notebook's id (`nb_...`).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "type": "string",
                      "const": "notebook",
                      "description": "Always `notebook`."
                    },
                    "id": {
                      "type": "string",
                      "description": "The notebook's id.",
                      "examples": [
                        "nb_8f2k"
                      ]
                    },
                    "slug": {
                      "type": "string",
                      "description": "Its short name."
                    },
                    "name": {
                      "type": "string",
                      "description": "Its name, as people read it."
                    },
                    "description": {
                      "type": "string",
                      "description": "What it holds; empty when none was given."
                    },
                    "access": {
                      "oneOf": [
                        {
                          "type": "object",
                          "properties": {
                            "mode": {
                              "type": "string",
                              "const": "all",
                              "description": "`all`: every user of the company may read it."
                            }
                          },
                          "required": [
                            "mode"
                          ]
                        },
                        {
                          "type": "object",
                          "properties": {
                            "mode": {
                              "type": "string",
                              "const": "named",
                              "description": "`named`: only the users listed may read it."
                            },
                            "user_ids": {
                              "maxItems": 1000,
                              "type": "array",
                              "items": {
                                "type": "string",
                                "minLength": 1,
                                "maxLength": 256
                              },
                              "description": "Your ids for the users who may read it, at most 1,000.",
                              "examples": [
                                [
                                  "traveller-42"
                                ]
                              ]
                            }
                          },
                          "required": [
                            "mode",
                            "user_ids"
                          ]
                        }
                      ],
                      "description": "Who may read it."
                    },
                    "document_count": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991,
                      "description": "How many documents it holds."
                    },
                    "bytes": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991,
                      "description": "The size of its text, in bytes, at most 5 MB."
                    },
                    "created_at": {
                      "type": "string",
                      "description": "When it was made, as an ISO 8601 date and time in UTC."
                    },
                    "updated_at": {
                      "type": "string",
                      "description": "When it last changed, as an ISO 8601 date and time in UTC."
                    }
                  },
                  "required": [
                    "object",
                    "id",
                    "slug",
                    "name",
                    "description",
                    "access",
                    "document_count",
                    "bytes",
                    "created_at",
                    "updated_at"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "patchNotebooksByNotebookId",
        "summary": "Rename it, or set who may read it: every user, or named users only.",
        "tags": [
          "Notebooks"
        ],
        "x-vestra-line": "deploy",
        "x-vestra-scope": "setup",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "notebook_id",
            "in": "path",
            "required": true,
            "description": "The notebook's id (`nb_...`).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "type": "string",
                      "const": "notebook",
                      "description": "Always `notebook`."
                    },
                    "id": {
                      "type": "string",
                      "description": "The notebook's id.",
                      "examples": [
                        "nb_8f2k"
                      ]
                    },
                    "slug": {
                      "type": "string",
                      "description": "Its short name."
                    },
                    "name": {
                      "type": "string",
                      "description": "Its name, as people read it."
                    },
                    "description": {
                      "type": "string",
                      "description": "What it holds; empty when none was given."
                    },
                    "access": {
                      "oneOf": [
                        {
                          "type": "object",
                          "properties": {
                            "mode": {
                              "type": "string",
                              "const": "all",
                              "description": "`all`: every user of the company may read it."
                            }
                          },
                          "required": [
                            "mode"
                          ]
                        },
                        {
                          "type": "object",
                          "properties": {
                            "mode": {
                              "type": "string",
                              "const": "named",
                              "description": "`named`: only the users listed may read it."
                            },
                            "user_ids": {
                              "maxItems": 1000,
                              "type": "array",
                              "items": {
                                "type": "string",
                                "minLength": 1,
                                "maxLength": 256
                              },
                              "description": "Your ids for the users who may read it, at most 1,000.",
                              "examples": [
                                [
                                  "traveller-42"
                                ]
                              ]
                            }
                          },
                          "required": [
                            "mode",
                            "user_ids"
                          ]
                        }
                      ],
                      "description": "Who may read it."
                    },
                    "document_count": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991,
                      "description": "How many documents it holds."
                    },
                    "bytes": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991,
                      "description": "The size of its text, in bytes, at most 5 MB."
                    },
                    "created_at": {
                      "type": "string",
                      "description": "When it was made, as an ISO 8601 date and time in UTC."
                    },
                    "updated_at": {
                      "type": "string",
                      "description": "When it last changed, as an ISO 8601 date and time in UTC."
                    }
                  },
                  "required": [
                    "object",
                    "id",
                    "slug",
                    "name",
                    "description",
                    "access",
                    "document_count",
                    "bytes",
                    "created_at",
                    "updated_at"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "description": "A new name, 1 to 80 characters.",
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 80
                  },
                  "description": {
                    "description": "A new description, up to 300 characters.",
                    "type": "string",
                    "maxLength": 300
                  },
                  "access": {
                    "description": "Who may read it, from now on.",
                    "oneOf": [
                      {
                        "type": "object",
                        "properties": {
                          "mode": {
                            "type": "string",
                            "const": "all",
                            "description": "`all`: every user of the company may read it."
                          }
                        },
                        "required": [
                          "mode"
                        ]
                      },
                      {
                        "type": "object",
                        "properties": {
                          "mode": {
                            "type": "string",
                            "const": "named",
                            "description": "`named`: only the users listed may read it."
                          },
                          "user_ids": {
                            "maxItems": 1000,
                            "type": "array",
                            "items": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 256
                            },
                            "description": "Your ids for the users who may read it, at most 1,000.",
                            "examples": [
                              [
                                "traveller-42"
                              ]
                            ]
                          }
                        },
                        "required": [
                          "mode",
                          "user_ids"
                        ]
                      }
                    ]
                  }
                },
                "additionalProperties": false
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteNotebooksByNotebookId",
        "summary": "Delete it.",
        "tags": [
          "Notebooks"
        ],
        "x-vestra-line": "deploy",
        "x-vestra-scope": "setup",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "notebook_id",
            "in": "path",
            "required": true,
            "description": "The notebook's id (`nb_...`).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "type": "string",
                      "const": "notebook",
                      "description": "Always `notebook`."
                    },
                    "id": {
                      "type": "string",
                      "description": "The notebook's id.",
                      "examples": [
                        "nb_8f2k"
                      ]
                    },
                    "deleted": {
                      "type": "boolean",
                      "const": true,
                      "description": "Always true: it is gone."
                    }
                  },
                  "required": [
                    "object",
                    "id",
                    "deleted"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/notebooks/{notebook_id}/documents": {
      "post": {
        "operationId": "postNotebooksByNotebookIdDocuments",
        "summary": "Add a document, as a file or as text.",
        "tags": [
          "Notebooks"
        ],
        "x-vestra-line": "deploy",
        "x-vestra-scope": "setup",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "notebook_id",
            "in": "path",
            "required": true,
            "description": "The notebook's id (`nb_...`).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 255
            },
            "description": "Send the same key to retry this call safely for 24 hours."
          }
        ],
        "responses": {
          "201": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "type": "string",
                      "const": "document",
                      "description": "Always `document`."
                    },
                    "id": {
                      "type": "string",
                      "description": "The document's id."
                    },
                    "notebook_id": {
                      "type": "string",
                      "description": "The notebook it is in."
                    },
                    "title": {
                      "type": "string",
                      "description": "Its title."
                    },
                    "content_type": {
                      "type": "string",
                      "description": "The type of its text, such as `text/markdown` or `text/plain`."
                    },
                    "bytes": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991,
                      "description": "Its size, in bytes."
                    },
                    "sha256": {
                      "type": "string",
                      "description": "A hash of its text."
                    },
                    "created_at": {
                      "type": "string",
                      "description": "When it was added, as an ISO 8601 date and time in UTC."
                    }
                  },
                  "required": [
                    "object",
                    "id",
                    "notebook_id",
                    "title",
                    "content_type",
                    "bytes",
                    "sha256",
                    "created_at"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "title": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 200,
                    "description": "Its title, 1 to 200 characters.",
                    "examples": [
                      "Refunds for cancelled flights"
                    ]
                  },
                  "text": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 524288,
                    "description": "Its text, up to 512 KB."
                  }
                },
                "required": [
                  "title",
                  "text"
                ],
                "additionalProperties": false
              }
            }
          }
        }
      },
      "get": {
        "operationId": "getNotebooksByNotebookIdDocuments",
        "summary": "Its documents.",
        "tags": [
          "Notebooks"
        ],
        "x-vestra-line": "deploy",
        "x-vestra-scope": "setup",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "notebook_id",
            "in": "path",
            "required": true,
            "description": "The notebook's id (`nb_...`).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "object": {
                            "type": "string",
                            "const": "document",
                            "description": "Always `document`."
                          },
                          "id": {
                            "type": "string",
                            "description": "The document's id."
                          },
                          "notebook_id": {
                            "type": "string",
                            "description": "The notebook it is in."
                          },
                          "title": {
                            "type": "string",
                            "description": "Its title."
                          },
                          "content_type": {
                            "type": "string",
                            "description": "The type of its text, such as `text/markdown` or `text/plain`."
                          },
                          "bytes": {
                            "type": "integer",
                            "minimum": -9007199254740991,
                            "maximum": 9007199254740991,
                            "description": "Its size, in bytes."
                          },
                          "sha256": {
                            "type": "string",
                            "description": "A hash of its text."
                          },
                          "created_at": {
                            "type": "string",
                            "description": "When it was added, as an ISO 8601 date and time in UTC."
                          }
                        },
                        "required": [
                          "object",
                          "id",
                          "notebook_id",
                          "title",
                          "content_type",
                          "bytes",
                          "sha256",
                          "created_at"
                        ]
                      },
                      "description": "The items on this page."
                    },
                    "next_cursor": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Send it as `cursor` for the next page; null on the last page."
                    }
                  },
                  "required": [
                    "data",
                    "next_cursor"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/notebooks/{notebook_id}/documents/{document_id}": {
      "delete": {
        "operationId": "deleteNotebooksByNotebookIdDocumentsByDocumentId",
        "summary": "Remove one.",
        "tags": [
          "Notebooks"
        ],
        "x-vestra-line": "deploy",
        "x-vestra-scope": "setup",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "notebook_id",
            "in": "path",
            "required": true,
            "description": "The notebook's id (`nb_...`).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "document_id",
            "in": "path",
            "required": true,
            "description": "The document's id (`doc_...`).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "type": "string",
                      "const": "document",
                      "description": "Always `document`."
                    },
                    "id": {
                      "type": "string",
                      "description": "The removed document's id."
                    },
                    "deleted": {
                      "type": "boolean",
                      "const": true,
                      "description": "Always true: it is gone."
                    }
                  },
                  "required": [
                    "object",
                    "id",
                    "deleted"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/memory": {
      "get": {
        "operationId": "getMemory",
        "summary": "What Bash remembers about one user (user_id), or the company's own Bash: the profile and the memories, newest first.",
        "tags": [
          "Memory"
        ],
        "x-vestra-line": "memory",
        "x-vestra-scope": "runtime",
        "security": [
          {
            "apiKey": []
          },
          {
            "clientToken": []
          }
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "default": 20,
              "description": "How many items per page, 1 to 100. Default 20.",
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "description": "Where to go on from: the `next_cursor` of the page before, unchanged. Absent: the first page.",
              "type": "string"
            }
          },
          {
            "name": "user_id",
            "in": "query",
            "required": false,
            "schema": {
              "description": "Whose memory, by your id for them. Absent: your company's own Bash's.",
              "type": "string",
              "pattern": "^[A-Za-z0-9][A-Za-z0-9._:@-]{0,127}$",
              "examples": [
                "traveller-42"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "profile": {
                      "anyOf": [
                        {
                          "type": "object",
                          "properties": {
                            "markdown": {
                              "type": "string",
                              "description": "The profile, as Markdown."
                            },
                            "updated_at": {
                              "anyOf": [
                                {
                                  "type": "string"
                                },
                                {
                                  "type": "null"
                                }
                              ],
                              "description": "When it last changed, as an ISO 8601 time; null when unknown."
                            }
                          },
                          "required": [
                            "markdown",
                            "updated_at"
                          ]
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "What Bash knows about the user, written up as one profile; null until it has one."
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "The memory (mem_...)."
                          },
                          "text": {
                            "type": "string",
                            "description": "What Bash remembers, in plain words.",
                            "examples": [
                              "Prefers a window seat."
                            ]
                          },
                          "kind": {
                            "type": "string",
                            "description": "What kind of fact it is, such as preference or identity."
                          },
                          "source": {
                            "type": "string",
                            "description": "How Bash learned it: user_direct (you or your user said so), tool_observed (seen in an app), upload, screen, or agent_inferred (worked out from the conversation)."
                          },
                          "observed_at": {
                            "type": "string",
                            "description": "When Bash learned it, as an ISO 8601 time."
                          }
                        },
                        "required": [
                          "id",
                          "text",
                          "kind",
                          "source",
                          "observed_at"
                        ]
                      },
                      "description": "The memories, one page of them."
                    },
                    "next_cursor": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Send it as cursor for the next page; null on the last."
                    }
                  },
                  "required": [
                    "profile",
                    "data",
                    "next_cursor"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "postMemory",
        "summary": "Tell Bash a fact once, for example 'prefers window seats', for one user (user_id) or the company's own Bash.",
        "tags": [
          "Memory"
        ],
        "x-vestra-line": "memory",
        "x-vestra-scope": "runtime",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 255
            },
            "description": "Send the same key to retry this call safely for 24 hours."
          }
        ],
        "responses": {
          "201": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "The memory (mem_...)."
                    },
                    "text": {
                      "type": "string",
                      "description": "What Bash remembers, in plain words.",
                      "examples": [
                        "Prefers a window seat."
                      ]
                    },
                    "kind": {
                      "type": "string",
                      "description": "What kind of fact it is, such as preference or identity."
                    },
                    "source": {
                      "type": "string",
                      "description": "How Bash learned it: user_direct (you or your user said so), tool_observed (seen in an app), upload, screen, or agent_inferred (worked out from the conversation)."
                    },
                    "observed_at": {
                      "type": "string",
                      "description": "When Bash learned it, as an ISO 8601 time."
                    }
                  },
                  "required": [
                    "id",
                    "text",
                    "kind",
                    "source",
                    "observed_at"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "user_id": {
                    "description": "Whose memory, by your id for them. Absent: your company's own Bash's.",
                    "type": "string",
                    "pattern": "^[A-Za-z0-9][A-Za-z0-9._:@-]{0,127}$",
                    "examples": [
                      "traveller-42"
                    ]
                  },
                  "text": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 1000,
                    "description": "The fact, in plain words: at most 1,000 characters.",
                    "examples": [
                      "Prefers a window seat."
                    ]
                  },
                  "kind": {
                    "default": "other",
                    "type": "string",
                    "enum": [
                      "identity",
                      "relationship",
                      "commitment",
                      "preference",
                      "project_state",
                      "other"
                    ],
                    "description": "What kind of fact it is: who they are (identity), who they know (relationship), what they promised (commitment), what they like (preference), where a piece of work stands (project_state), or other."
                  }
                },
                "required": [
                  "text"
                ]
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteMemory",
        "summary": "Forget everything about one user (user_id), or the company's own Bash.",
        "tags": [
          "Memory"
        ],
        "x-vestra-line": "memory",
        "x-vestra-scope": "runtime",
        "security": [
          {
            "apiKey": []
          },
          {
            "clientToken": []
          }
        ],
        "parameters": [
          {
            "name": "user_id",
            "in": "query",
            "required": false,
            "schema": {
              "description": "Whose memory, by your id for them. Absent: your company's own Bash's.",
              "type": "string",
              "pattern": "^[A-Za-z0-9][A-Za-z0-9._:@-]{0,127}$",
              "examples": [
                "traveller-42"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "user_id": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Whose memory it was, by your id for them; null for your company's own Bash."
                    },
                    "deleted": {
                      "type": "boolean",
                      "const": true,
                      "description": "Always true: Bash no longer remembers any of it."
                    },
                    "memories_deleted": {
                      "type": "integer",
                      "minimum": 0,
                      "maximum": 9007199254740991,
                      "description": "How many memories were forgotten."
                    }
                  },
                  "required": [
                    "user_id",
                    "deleted",
                    "memories_deleted"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/memory/search": {
      "get": {
        "operationId": "getMemorySearch",
        "summary": "Ask the memory a question (q), for one user (user_id) or the company's own Bash.",
        "tags": [
          "Memory"
        ],
        "x-vestra-line": "memory",
        "x-vestra-scope": "runtime",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "user_id",
            "in": "query",
            "required": false,
            "schema": {
              "description": "Whose memory, by your id for them. Absent: your company's own Bash's.",
              "type": "string",
              "pattern": "^[A-Za-z0-9][A-Za-z0-9._:@-]{0,127}$",
              "examples": [
                "traveller-42"
              ]
            }
          },
          {
            "name": "q",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 500,
              "description": "What to ask the memory, in at most 500 characters.",
              "examples": [
                "Which seat does she like?"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "query": {
                      "type": "string",
                      "description": "What you asked."
                    },
                    "found": {
                      "type": "boolean",
                      "description": "Whether the memory had an answer."
                    },
                    "text": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The answer, in plain words; null when nothing was found."
                    }
                  },
                  "required": [
                    "query",
                    "found",
                    "text"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/memory/{memory_id}": {
      "delete": {
        "operationId": "deleteMemoryByMemoryId",
        "summary": "Forget one thing. user_id names whose memory it is.",
        "tags": [
          "Memory"
        ],
        "x-vestra-line": "memory",
        "x-vestra-scope": "runtime",
        "security": [
          {
            "apiKey": []
          },
          {
            "clientToken": []
          }
        ],
        "parameters": [
          {
            "name": "memory_id",
            "in": "path",
            "required": true,
            "description": "The memory's id (`mem_...`).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "user_id",
            "in": "query",
            "required": false,
            "schema": {
              "description": "Whose memory, by your id for them. Absent: your company's own Bash's.",
              "type": "string",
              "pattern": "^[A-Za-z0-9][A-Za-z0-9._:@-]{0,127}$",
              "examples": [
                "traveller-42"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "The memory (mem_...)."
                    },
                    "deleted": {
                      "type": "boolean",
                      "const": true,
                      "description": "Always true: Bash no longer remembers it."
                    }
                  },
                  "required": [
                    "id",
                    "deleted"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/deployments": {
      "get": {
        "operationId": "getDeployments",
        "summary": "Your deployments.",
        "tags": [
          "Deployments"
        ],
        "x-vestra-line": "deploy",
        "x-vestra-scope": "setup",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "default": 20,
              "description": "How many items per page, 1 to 100. Default 20.",
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "description": "Where to go on from: the `next_cursor` of the page before, unchanged. Absent: the first page.",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "The deployment's id.",
                            "examples": [
                              "dep_8f2k"
                            ]
                          },
                          "object": {
                            "type": "string",
                            "const": "deployment",
                            "description": "Always `deployment`."
                          },
                          "name": {
                            "type": "string",
                            "description": "Its name, as people read it."
                          },
                          "slug": {
                            "type": "string",
                            "description": "Its name in URLs and refs: send it where a route takes `{deployment_id}`.",
                            "examples": [
                              "trip-rescue"
                            ]
                          },
                          "description": {
                            "type": "string",
                            "description": "What it is for; empty when none was given."
                          },
                          "base": {
                            "type": "string",
                            "const": "bash",
                            "description": "What it is built on: always `bash`."
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "active",
                              "archived"
                            ],
                            "description": "`active`, or `archived` (put away: no new conversation or version reaches it)."
                          },
                          "draft_version": {
                            "type": "integer",
                            "minimum": -9007199254740991,
                            "maximum": 9007199254740991,
                            "description": "The version test keys run. A new save moves it there; a promote with a test key moves it to the version named, older ones included."
                          },
                          "live_version": {
                            "anyOf": [
                              {
                                "type": "integer",
                                "minimum": -9007199254740991,
                                "maximum": 9007199254740991
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "The version live keys run; null until one is promoted."
                          },
                          "created_at": {
                            "type": "string",
                            "description": "When it was made, as an ISO 8601 date and time in UTC."
                          },
                          "updated_at": {
                            "type": "string",
                            "description": "When it last changed, as an ISO 8601 date and time in UTC."
                          }
                        },
                        "required": [
                          "id",
                          "object",
                          "name",
                          "slug",
                          "description",
                          "base",
                          "status",
                          "draft_version",
                          "live_version",
                          "created_at",
                          "updated_at"
                        ]
                      },
                      "description": "The items on this page."
                    },
                    "next_cursor": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Send it as `cursor` for the next page; null on the last page."
                    }
                  },
                  "required": [
                    "data",
                    "next_cursor"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "postDeployments",
        "summary": "Create one on base 'bash'. It starts with a draft version.",
        "tags": [
          "Deployments"
        ],
        "x-vestra-line": "deploy",
        "x-vestra-scope": "setup",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 255
            },
            "description": "Send the same key to retry this call safely for 24 hours."
          }
        ],
        "responses": {
          "201": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "The deployment's id.",
                      "examples": [
                        "dep_8f2k"
                      ]
                    },
                    "object": {
                      "type": "string",
                      "const": "deployment",
                      "description": "Always `deployment`."
                    },
                    "name": {
                      "type": "string",
                      "description": "Its name, as people read it."
                    },
                    "slug": {
                      "type": "string",
                      "description": "Its name in URLs and refs: send it where a route takes `{deployment_id}`.",
                      "examples": [
                        "trip-rescue"
                      ]
                    },
                    "description": {
                      "type": "string",
                      "description": "What it is for; empty when none was given."
                    },
                    "base": {
                      "type": "string",
                      "const": "bash",
                      "description": "What it is built on: always `bash`."
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "active",
                        "archived"
                      ],
                      "description": "`active`, or `archived` (put away: no new conversation or version reaches it)."
                    },
                    "draft_version": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991,
                      "description": "The version test keys run. A new save moves it there; a promote with a test key moves it to the version named, older ones included."
                    },
                    "live_version": {
                      "anyOf": [
                        {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The version live keys run; null until one is promoted."
                    },
                    "created_at": {
                      "type": "string",
                      "description": "When it was made, as an ISO 8601 date and time in UTC."
                    },
                    "updated_at": {
                      "type": "string",
                      "description": "When it last changed, as an ISO 8601 date and time in UTC."
                    }
                  },
                  "required": [
                    "id",
                    "object",
                    "name",
                    "slug",
                    "description",
                    "base",
                    "status",
                    "draft_version",
                    "live_version",
                    "created_at",
                    "updated_at"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 120,
                    "description": "Its name, as people read it, 1 to 120 characters.",
                    "examples": [
                      "Trip rescue"
                    ]
                  },
                  "slug": {
                    "description": "Its name in URLs and refs: lowercase letters, digits and dashes, up to 63. Absent: made from `name`.",
                    "examples": [
                      "trip-rescue"
                    ],
                    "type": "string",
                    "pattern": "^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$"
                  },
                  "description": {
                    "description": "What it is for, up to 2,000 characters.",
                    "type": "string",
                    "maxLength": 2000
                  },
                  "manifest": {
                    "type": "object",
                    "propertyNames": {
                      "type": "string"
                    },
                    "additionalProperties": {},
                    "description": "The version's settings as a manifest: `instructions`, `language`, `model`, `mcp_servers`, `mcp_tool_policy`, `apps`, `approvals`, `memory`, `notebooks`, `skills`, `tools`, `environment`, `browser` and `limits`. A field left out takes its default."
                  },
                  "note": {
                    "description": "A note on this version, up to 500 characters, such as what changed.",
                    "examples": [
                      "Adds the refund tool."
                    ],
                    "type": "string",
                    "maxLength": 500
                  }
                },
                "required": [
                  "name"
                ]
              }
            }
          }
        }
      }
    },
    "/v1/deployments/{deployment_id}": {
      "get": {
        "operationId": "getDeploymentsByDeploymentId",
        "summary": "One deployment, by its id or its name: the live version and the draft. With format=yaml, its latest version as vestra.yaml.",
        "tags": [
          "Deployments"
        ],
        "x-vestra-line": "deploy",
        "x-vestra-scope": "setup",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "deployment_id",
            "in": "path",
            "required": true,
            "description": "The deployment's id (`dep_...`). The /v1/deployments routes also take its name.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "format",
            "in": "query",
            "required": false,
            "schema": {
              "default": "json",
              "description": "`json` (the default): the deployment. `yaml`: its newest version, as vestra.yaml.",
              "type": "string",
              "enum": [
                "json",
                "yaml"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "The deployment's id.",
                      "examples": [
                        "dep_8f2k"
                      ]
                    },
                    "object": {
                      "type": "string",
                      "const": "deployment",
                      "description": "Always `deployment`."
                    },
                    "name": {
                      "type": "string",
                      "description": "Its name, as people read it."
                    },
                    "slug": {
                      "type": "string",
                      "description": "Its name in URLs and refs: send it where a route takes `{deployment_id}`.",
                      "examples": [
                        "trip-rescue"
                      ]
                    },
                    "description": {
                      "type": "string",
                      "description": "What it is for; empty when none was given."
                    },
                    "base": {
                      "type": "string",
                      "const": "bash",
                      "description": "What it is built on: always `bash`."
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "active",
                        "archived"
                      ],
                      "description": "`active`, or `archived` (put away: no new conversation or version reaches it)."
                    },
                    "draft_version": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991,
                      "description": "The version test keys run. A new save moves it there; a promote with a test key moves it to the version named, older ones included."
                    },
                    "live_version": {
                      "anyOf": [
                        {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The version live keys run; null until one is promoted."
                    },
                    "created_at": {
                      "type": "string",
                      "description": "When it was made, as an ISO 8601 date and time in UTC."
                    },
                    "updated_at": {
                      "type": "string",
                      "description": "When it last changed, as an ISO 8601 date and time in UTC."
                    }
                  },
                  "required": [
                    "id",
                    "object",
                    "name",
                    "slug",
                    "description",
                    "base",
                    "status",
                    "draft_version",
                    "live_version",
                    "created_at",
                    "updated_at"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      },
      "put": {
        "operationId": "putDeploymentsByDeploymentId",
        "summary": "Apply a whole vestra.yaml, sent as JSON, by the deployment's name: the first call makes it, and a file that changes nothing makes no version (changed: []). MCP servers are registered by URL, and the tool policy the file gives each one is this version's own, on top of the server's floor, from the moment the version runs. Tests become scenarios, and the routines and webhooks the file declares are its own. ?promote=after_tests (the default), now or no promotes in the key's mode. 400 secret_missing names the secrets to store first; 409 mcp_server_shared names the other deployments that run an MCP server whose headers the file would change.",
        "tags": [
          "Deployments"
        ],
        "x-vestra-line": "deploy",
        "x-vestra-scope": "setup",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "deployment_id",
            "in": "path",
            "required": true,
            "description": "The deployment's id (`dep_...`). The /v1/deployments routes also take its name.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "promote",
            "in": "query",
            "required": false,
            "schema": {
              "default": "after_tests",
              "description": "When the new version goes live in the key's mode: `after_tests` (the default) once the file's tests pass, `now`, or `no`.",
              "type": "string",
              "enum": [
                "after_tests",
                "now",
                "no"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "type": "string",
                      "const": "deployment_apply",
                      "description": "Always `deployment_apply`."
                    },
                    "deployment": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "The deployment's id.",
                          "examples": [
                            "dep_8f2k"
                          ]
                        },
                        "object": {
                          "type": "string",
                          "const": "deployment",
                          "description": "Always `deployment`."
                        },
                        "name": {
                          "type": "string",
                          "description": "Its name, as people read it."
                        },
                        "slug": {
                          "type": "string",
                          "description": "Its name in URLs and refs: send it where a route takes `{deployment_id}`.",
                          "examples": [
                            "trip-rescue"
                          ]
                        },
                        "description": {
                          "type": "string",
                          "description": "What it is for; empty when none was given."
                        },
                        "base": {
                          "type": "string",
                          "const": "bash",
                          "description": "What it is built on: always `bash`."
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "active",
                            "archived"
                          ],
                          "description": "`active`, or `archived` (put away: no new conversation or version reaches it)."
                        },
                        "draft_version": {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991,
                          "description": "The version test keys run. A new save moves it there; a promote with a test key moves it to the version named, older ones included."
                        },
                        "live_version": {
                          "anyOf": [
                            {
                              "type": "integer",
                              "minimum": -9007199254740991,
                              "maximum": 9007199254740991
                            },
                            {
                              "type": "null"
                            }
                          ],
                          "description": "The version live keys run; null until one is promoted."
                        },
                        "created_at": {
                          "type": "string",
                          "description": "When it was made, as an ISO 8601 date and time in UTC."
                        },
                        "updated_at": {
                          "type": "string",
                          "description": "When it last changed, as an ISO 8601 date and time in UTC."
                        }
                      },
                      "required": [
                        "id",
                        "object",
                        "name",
                        "slug",
                        "description",
                        "base",
                        "status",
                        "draft_version",
                        "live_version",
                        "created_at",
                        "updated_at"
                      ],
                      "description": "The deployment, after the apply."
                    },
                    "version": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991,
                      "description": "The version this file is: new, or the latest when nothing changed."
                    },
                    "changed": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "The file's fields that differ from the version before, in the file's order; empty when nothing changed.",
                      "examples": [
                        [
                          "instructions",
                          "tools"
                        ]
                      ]
                    },
                    "tests": {
                      "anyOf": [
                        {
                          "type": "object",
                          "properties": {
                            "id": {
                              "type": "string",
                              "description": "The test run's id.",
                              "examples": [
                                "trun_8f2k"
                              ]
                            },
                            "object": {
                              "type": "string",
                              "const": "test_run",
                              "description": "Always `test_run`."
                            },
                            "deployment_id": {
                              "type": "string",
                              "description": "The deployment it tests."
                            },
                            "version": {
                              "type": "integer",
                              "minimum": -9007199254740991,
                              "maximum": 9007199254740991,
                              "description": "The version it tests."
                            },
                            "status": {
                              "type": "string",
                              "enum": [
                                "queued",
                                "running",
                                "passed",
                                "failed",
                                "error"
                              ],
                              "description": "`queued` or `running` while it plays. `passed`: every scenario passed. `failed`: one or more did not. `error`: it could not finish, as `error_code` says."
                            },
                            "error_code": {
                              "anyOf": [
                                {
                                  "type": "string"
                                },
                                {
                                  "type": "null"
                                }
                              ],
                              "description": "Why it ended in `error`: `interrupted` (a restart stopped it too often), `test_wallet_empty`, `judge_unreadable` (the grader's answer could not be read) or `internal`. Null otherwise."
                            },
                            "scenario_count": {
                              "type": "integer",
                              "minimum": -9007199254740991,
                              "maximum": 9007199254740991,
                              "description": "How many scenarios it plays."
                            },
                            "passed_count": {
                              "type": "integer",
                              "minimum": -9007199254740991,
                              "maximum": 9007199254740991,
                              "description": "How many have passed so far."
                            },
                            "resumes": {
                              "type": "integer",
                              "minimum": -9007199254740991,
                              "maximum": 9007199254740991,
                              "description": "How many times a restart interrupted it and it played on from where it was, at most 2."
                            },
                            "promoted": {
                              "anyOf": [
                                {
                                  "type": "object",
                                  "properties": {
                                    "mode": {
                                      "type": "string",
                                      "enum": [
                                        "live",
                                        "test"
                                      ],
                                      "description": "The mode the version went live in."
                                    },
                                    "version": {
                                      "type": "integer",
                                      "minimum": -9007199254740991,
                                      "maximum": 9007199254740991,
                                      "description": "The version that went live."
                                    }
                                  },
                                  "required": [
                                    "mode",
                                    "version"
                                  ]
                                },
                                {
                                  "type": "null"
                                }
                              ],
                              "description": "What its pass promoted, for an apply that promotes after its tests; null when it promoted nothing (none asked, refused, or it did not pass)."
                            },
                            "became_default": {
                              "type": "boolean",
                              "description": "True when that promotion made the deployment the company's default: an ask with no deployment now reaches it."
                            },
                            "cost_usd": {
                              "type": "number",
                              "description": "What the run cost, in billed US dollars."
                            },
                            "created_at": {
                              "type": "string",
                              "description": "When it was asked for, as an ISO 8601 date and time in UTC."
                            },
                            "started_at": {
                              "anyOf": [
                                {
                                  "type": "string"
                                },
                                {
                                  "type": "null"
                                }
                              ],
                              "description": "When it began to play; null while queued."
                            },
                            "finished_at": {
                              "anyOf": [
                                {
                                  "type": "string"
                                },
                                {
                                  "type": "null"
                                }
                              ],
                              "description": "When it ended; null while it plays."
                            },
                            "results": {
                              "description": "Each scenario's result, on GET /v1/test-runs/{test_run_id}; absent in lists.",
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "object": {
                                    "type": "string",
                                    "const": "test_result",
                                    "description": "Always `test_result`."
                                  },
                                  "scenario_id": {
                                    "anyOf": [
                                      {
                                        "type": "string"
                                      },
                                      {
                                        "type": "null"
                                      }
                                    ],
                                    "description": "The scenario it played; null when the scenario was deleted since."
                                  },
                                  "scenario": {
                                    "type": "object",
                                    "properties": {
                                      "name": {
                                        "type": "string",
                                        "minLength": 1,
                                        "maxLength": 120,
                                        "description": "Its name, 1 to 120 characters.",
                                        "examples": [
                                          "Bag allowance"
                                        ]
                                      },
                                      "persona": {
                                        "type": "string",
                                        "minLength": 1,
                                        "maxLength": 2000,
                                        "description": "Who the test user is, in a few sentences, up to 2,000 characters.",
                                        "examples": [
                                          "A first-time flyer, anxious, on a phone."
                                        ]
                                      },
                                      "goal": {
                                        "type": "string",
                                        "minLength": 1,
                                        "maxLength": 2000,
                                        "description": "What the test user wants, in their words, up to 2,000 characters.",
                                        "examples": [
                                          "How many kilos can I take on booking TN-48213?"
                                        ]
                                      },
                                      "success_criteria": {
                                        "minItems": 1,
                                        "maxItems": 12,
                                        "type": "array",
                                        "items": {
                                          "type": "string",
                                          "minLength": 1,
                                          "maxLength": 500
                                        },
                                        "description": "What a pass looks like: 1 to 12 lines, each up to 500 characters. Every one must be met.",
                                        "examples": [
                                          [
                                            "Says 7 kg of cabin baggage."
                                          ]
                                        ]
                                      },
                                      "must_never": {
                                        "default": [],
                                        "maxItems": 12,
                                        "type": "array",
                                        "items": {
                                          "type": "string",
                                          "minLength": 1,
                                          "maxLength": 500
                                        },
                                        "description": "What must never happen: up to 12 lines, each up to 500 characters. Any one fails the test.",
                                        "examples": [
                                          [
                                            "Promises a refund."
                                          ]
                                        ]
                                      },
                                      "tool_results": {
                                        "description": "What each tool answers in this test, as any JSON, at most 20: a declared tool by its name, and a tool of an MCP server as <server>.<tool> (the server's slug), since a test never runs one for real unless the server marks it read-only. A tool with none answers an error.",
                                        "examples": [
                                          {
                                            "get_booking": {
                                              "cabin_kg": 7
                                            }
                                          }
                                        ],
                                        "type": "object",
                                        "propertyNames": {
                                          "type": "string",
                                          "pattern": "^(?!mcp__)(?:[a-z][a-z0-9_]{0,63}|[a-z][a-z0-9-]{0,39}\\.[A-Za-z0-9_.-]{1,128})$"
                                        },
                                        "additionalProperties": {}
                                      },
                                      "approves": {
                                        "description": "true: the test user says yes to each approval for a tool of one of the deployment's own MCP servers, which in a test plays its tool_results entry or does not run. Absent or false: it says no to every approval. Anything else that waits for a yes is always declined.",
                                        "examples": [
                                          true
                                        ],
                                        "type": "boolean"
                                      }
                                    },
                                    "required": [
                                      "name",
                                      "persona",
                                      "goal",
                                      "success_criteria",
                                      "must_never"
                                    ],
                                    "description": "The scenario as it was played."
                                  },
                                  "verdict": {
                                    "type": "string",
                                    "enum": [
                                      "passed",
                                      "failed",
                                      "error"
                                    ],
                                    "description": "`passed`: every line of success met and nothing it must never do. `failed`: not so. `error`: it could not be played to the end."
                                  },
                                  "reason": {
                                    "type": "string",
                                    "description": "Why, in a sentence or two."
                                  },
                                  "criteria": {
                                    "type": "array",
                                    "items": {
                                      "type": "object",
                                      "properties": {
                                        "criterion": {
                                          "type": "string",
                                          "description": "One line of what a pass looks like."
                                        },
                                        "met": {
                                          "type": "boolean",
                                          "description": "Whether the conversation met it."
                                        },
                                        "evidence": {
                                          "type": "string",
                                          "description": "Why the grader says so, from the conversation."
                                        }
                                      },
                                      "required": [
                                        "criterion",
                                        "met",
                                        "evidence"
                                      ]
                                    },
                                    "description": "Each line of success, graded."
                                  },
                                  "must_never": {
                                    "type": "array",
                                    "items": {
                                      "type": "object",
                                      "properties": {
                                        "rule": {
                                          "type": "string",
                                          "description": "One line of what must never happen."
                                        },
                                        "violated": {
                                          "type": "boolean",
                                          "description": "Whether it happened."
                                        },
                                        "evidence": {
                                          "type": "string",
                                          "description": "Why the grader says so, from the conversation."
                                        }
                                      },
                                      "required": [
                                        "rule",
                                        "violated",
                                        "evidence"
                                      ]
                                    },
                                    "description": "Each thing it must never do, graded."
                                  },
                                  "approvals_asked": {
                                    "type": "array",
                                    "items": {
                                      "type": "object",
                                      "properties": {
                                        "kind": {
                                          "type": "string",
                                          "description": "The kind of ask Bash raised, such as `hands_approval`, `credit_approval` or `tool_permission`."
                                        },
                                        "category": {
                                          "type": "string",
                                          "enum": [
                                            "payment",
                                            "account_action",
                                            "connect_app",
                                            "action",
                                            "custom"
                                          ],
                                          "description": "What it would have done: a `payment`, an `account_action`, `connect_app`, another `action`, or `custom`."
                                        },
                                        "summary": {
                                          "type": "string",
                                          "description": "What it asked to do, in its words."
                                        },
                                        "decision": {
                                          "type": "string",
                                          "enum": [
                                            "denied",
                                            "approved"
                                          ],
                                          "description": "What the test user said. It denies anything that would act for it, so a test never moves money or changes an account; a test with approves: true approves the tools of the deployment's own MCP servers, which a test plays from its tool_results or does not run."
                                        }
                                      },
                                      "required": [
                                        "kind",
                                        "category",
                                        "summary",
                                        "decision"
                                      ]
                                    },
                                    "description": "What Bash asked the test user's yes for, and what it said."
                                  },
                                  "transcript": {
                                    "type": "array",
                                    "items": {
                                      "type": "object",
                                      "properties": {
                                        "role": {
                                          "type": "string",
                                          "enum": [
                                            "customer",
                                            "bash",
                                            "note"
                                          ],
                                          "description": "Who said it: `customer` (the test user), `bash`, or a `note` on what happened (work started, a tool called)."
                                        },
                                        "text": {
                                          "type": "string",
                                          "description": "What was said, or what happened."
                                        }
                                      },
                                      "required": [
                                        "role",
                                        "text"
                                      ]
                                    },
                                    "description": "The conversation, line by line."
                                  },
                                  "conversation_id": {
                                    "anyOf": [
                                      {
                                        "type": "string"
                                      },
                                      {
                                        "type": "null"
                                      }
                                    ],
                                    "description": "The test conversation; null when it never started."
                                  },
                                  "cost_usd": {
                                    "type": "number",
                                    "description": "What playing it cost, in billed US dollars."
                                  }
                                },
                                "required": [
                                  "object",
                                  "scenario_id",
                                  "scenario",
                                  "verdict",
                                  "reason",
                                  "criteria",
                                  "must_never",
                                  "approvals_asked",
                                  "transcript",
                                  "conversation_id",
                                  "cost_usd"
                                ]
                              }
                            }
                          },
                          "required": [
                            "id",
                            "object",
                            "deployment_id",
                            "version",
                            "status",
                            "error_code",
                            "scenario_count",
                            "passed_count",
                            "resumes",
                            "promoted",
                            "became_default",
                            "cost_usd",
                            "created_at",
                            "started_at",
                            "finished_at"
                          ]
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The test run this apply started; null when it started none."
                    },
                    "promote": {
                      "type": "object",
                      "properties": {
                        "when": {
                          "type": "string",
                          "enum": [
                            "after_tests",
                            "now",
                            "no"
                          ],
                          "description": "When it was asked to go live: `after_tests`, `now` or `no`."
                        },
                        "mode": {
                          "type": "string",
                          "enum": [
                            "live",
                            "test"
                          ],
                          "description": "The key's mode: `live` moves `live_version`, `test` moves `draft_version`."
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "promoted",
                            "already",
                            "waiting",
                            "not_promoted"
                          ],
                          "description": "`promoted`: this call moved it. `already`: that mode already runs this version. `waiting`: its tests run first. `not_promoted`: see `code`."
                        },
                        "code": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ],
                          "description": "Why it was not promoted, as an error code; null when you sent `promote=no`. After `promoted` or `already`: the first thing in the file that could not be made in this mode, such as a missing secret. Fix it and apply the file again."
                        },
                        "message": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ],
                          "description": "The same, in a sentence a person can read; null with no `code`."
                        }
                      },
                      "required": [
                        "when",
                        "mode",
                        "status",
                        "code",
                        "message"
                      ],
                      "description": "Whether, and when, the version goes live."
                    },
                    "new_webhooks": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "The webhook endpoint's id."
                          },
                          "url": {
                            "type": "string",
                            "description": "Where its events go."
                          },
                          "secret": {
                            "type": "string",
                            "description": "Its signing secret, shown here once: store it to check each delivery."
                          }
                        },
                        "required": [
                          "id",
                          "url",
                          "secret"
                        ]
                      },
                      "description": "The webhook endpoints this call made, each with its signing secret."
                    },
                    "became_default": {
                      "type": "boolean",
                      "description": "True when this made the deployment the company's default, which it had none of: an ask that names no deployment now reaches it. A promotion that waits for its tests sets it when they pass."
                    }
                  },
                  "required": [
                    "object",
                    "deployment",
                    "version",
                    "changed",
                    "tests",
                    "promote",
                    "new_webhooks",
                    "became_default"
                  ]
                }
              }
            }
          },
          "201": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "type": "string",
                      "const": "deployment_apply",
                      "description": "Always `deployment_apply`."
                    },
                    "deployment": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "The deployment's id.",
                          "examples": [
                            "dep_8f2k"
                          ]
                        },
                        "object": {
                          "type": "string",
                          "const": "deployment",
                          "description": "Always `deployment`."
                        },
                        "name": {
                          "type": "string",
                          "description": "Its name, as people read it."
                        },
                        "slug": {
                          "type": "string",
                          "description": "Its name in URLs and refs: send it where a route takes `{deployment_id}`.",
                          "examples": [
                            "trip-rescue"
                          ]
                        },
                        "description": {
                          "type": "string",
                          "description": "What it is for; empty when none was given."
                        },
                        "base": {
                          "type": "string",
                          "const": "bash",
                          "description": "What it is built on: always `bash`."
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "active",
                            "archived"
                          ],
                          "description": "`active`, or `archived` (put away: no new conversation or version reaches it)."
                        },
                        "draft_version": {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991,
                          "description": "The version test keys run. A new save moves it there; a promote with a test key moves it to the version named, older ones included."
                        },
                        "live_version": {
                          "anyOf": [
                            {
                              "type": "integer",
                              "minimum": -9007199254740991,
                              "maximum": 9007199254740991
                            },
                            {
                              "type": "null"
                            }
                          ],
                          "description": "The version live keys run; null until one is promoted."
                        },
                        "created_at": {
                          "type": "string",
                          "description": "When it was made, as an ISO 8601 date and time in UTC."
                        },
                        "updated_at": {
                          "type": "string",
                          "description": "When it last changed, as an ISO 8601 date and time in UTC."
                        }
                      },
                      "required": [
                        "id",
                        "object",
                        "name",
                        "slug",
                        "description",
                        "base",
                        "status",
                        "draft_version",
                        "live_version",
                        "created_at",
                        "updated_at"
                      ],
                      "description": "The deployment, after the apply."
                    },
                    "version": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991,
                      "description": "The version this file is: new, or the latest when nothing changed."
                    },
                    "changed": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "The file's fields that differ from the version before, in the file's order; empty when nothing changed.",
                      "examples": [
                        [
                          "instructions",
                          "tools"
                        ]
                      ]
                    },
                    "tests": {
                      "anyOf": [
                        {
                          "type": "object",
                          "properties": {
                            "id": {
                              "type": "string",
                              "description": "The test run's id.",
                              "examples": [
                                "trun_8f2k"
                              ]
                            },
                            "object": {
                              "type": "string",
                              "const": "test_run",
                              "description": "Always `test_run`."
                            },
                            "deployment_id": {
                              "type": "string",
                              "description": "The deployment it tests."
                            },
                            "version": {
                              "type": "integer",
                              "minimum": -9007199254740991,
                              "maximum": 9007199254740991,
                              "description": "The version it tests."
                            },
                            "status": {
                              "type": "string",
                              "enum": [
                                "queued",
                                "running",
                                "passed",
                                "failed",
                                "error"
                              ],
                              "description": "`queued` or `running` while it plays. `passed`: every scenario passed. `failed`: one or more did not. `error`: it could not finish, as `error_code` says."
                            },
                            "error_code": {
                              "anyOf": [
                                {
                                  "type": "string"
                                },
                                {
                                  "type": "null"
                                }
                              ],
                              "description": "Why it ended in `error`: `interrupted` (a restart stopped it too often), `test_wallet_empty`, `judge_unreadable` (the grader's answer could not be read) or `internal`. Null otherwise."
                            },
                            "scenario_count": {
                              "type": "integer",
                              "minimum": -9007199254740991,
                              "maximum": 9007199254740991,
                              "description": "How many scenarios it plays."
                            },
                            "passed_count": {
                              "type": "integer",
                              "minimum": -9007199254740991,
                              "maximum": 9007199254740991,
                              "description": "How many have passed so far."
                            },
                            "resumes": {
                              "type": "integer",
                              "minimum": -9007199254740991,
                              "maximum": 9007199254740991,
                              "description": "How many times a restart interrupted it and it played on from where it was, at most 2."
                            },
                            "promoted": {
                              "anyOf": [
                                {
                                  "type": "object",
                                  "properties": {
                                    "mode": {
                                      "type": "string",
                                      "enum": [
                                        "live",
                                        "test"
                                      ],
                                      "description": "The mode the version went live in."
                                    },
                                    "version": {
                                      "type": "integer",
                                      "minimum": -9007199254740991,
                                      "maximum": 9007199254740991,
                                      "description": "The version that went live."
                                    }
                                  },
                                  "required": [
                                    "mode",
                                    "version"
                                  ]
                                },
                                {
                                  "type": "null"
                                }
                              ],
                              "description": "What its pass promoted, for an apply that promotes after its tests; null when it promoted nothing (none asked, refused, or it did not pass)."
                            },
                            "became_default": {
                              "type": "boolean",
                              "description": "True when that promotion made the deployment the company's default: an ask with no deployment now reaches it."
                            },
                            "cost_usd": {
                              "type": "number",
                              "description": "What the run cost, in billed US dollars."
                            },
                            "created_at": {
                              "type": "string",
                              "description": "When it was asked for, as an ISO 8601 date and time in UTC."
                            },
                            "started_at": {
                              "anyOf": [
                                {
                                  "type": "string"
                                },
                                {
                                  "type": "null"
                                }
                              ],
                              "description": "When it began to play; null while queued."
                            },
                            "finished_at": {
                              "anyOf": [
                                {
                                  "type": "string"
                                },
                                {
                                  "type": "null"
                                }
                              ],
                              "description": "When it ended; null while it plays."
                            },
                            "results": {
                              "description": "Each scenario's result, on GET /v1/test-runs/{test_run_id}; absent in lists.",
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "object": {
                                    "type": "string",
                                    "const": "test_result",
                                    "description": "Always `test_result`."
                                  },
                                  "scenario_id": {
                                    "anyOf": [
                                      {
                                        "type": "string"
                                      },
                                      {
                                        "type": "null"
                                      }
                                    ],
                                    "description": "The scenario it played; null when the scenario was deleted since."
                                  },
                                  "scenario": {
                                    "type": "object",
                                    "properties": {
                                      "name": {
                                        "type": "string",
                                        "minLength": 1,
                                        "maxLength": 120,
                                        "description": "Its name, 1 to 120 characters.",
                                        "examples": [
                                          "Bag allowance"
                                        ]
                                      },
                                      "persona": {
                                        "type": "string",
                                        "minLength": 1,
                                        "maxLength": 2000,
                                        "description": "Who the test user is, in a few sentences, up to 2,000 characters.",
                                        "examples": [
                                          "A first-time flyer, anxious, on a phone."
                                        ]
                                      },
                                      "goal": {
                                        "type": "string",
                                        "minLength": 1,
                                        "maxLength": 2000,
                                        "description": "What the test user wants, in their words, up to 2,000 characters.",
                                        "examples": [
                                          "How many kilos can I take on booking TN-48213?"
                                        ]
                                      },
                                      "success_criteria": {
                                        "minItems": 1,
                                        "maxItems": 12,
                                        "type": "array",
                                        "items": {
                                          "type": "string",
                                          "minLength": 1,
                                          "maxLength": 500
                                        },
                                        "description": "What a pass looks like: 1 to 12 lines, each up to 500 characters. Every one must be met.",
                                        "examples": [
                                          [
                                            "Says 7 kg of cabin baggage."
                                          ]
                                        ]
                                      },
                                      "must_never": {
                                        "default": [],
                                        "maxItems": 12,
                                        "type": "array",
                                        "items": {
                                          "type": "string",
                                          "minLength": 1,
                                          "maxLength": 500
                                        },
                                        "description": "What must never happen: up to 12 lines, each up to 500 characters. Any one fails the test.",
                                        "examples": [
                                          [
                                            "Promises a refund."
                                          ]
                                        ]
                                      },
                                      "tool_results": {
                                        "description": "What each tool answers in this test, as any JSON, at most 20: a declared tool by its name, and a tool of an MCP server as <server>.<tool> (the server's slug), since a test never runs one for real unless the server marks it read-only. A tool with none answers an error.",
                                        "examples": [
                                          {
                                            "get_booking": {
                                              "cabin_kg": 7
                                            }
                                          }
                                        ],
                                        "type": "object",
                                        "propertyNames": {
                                          "type": "string",
                                          "pattern": "^(?!mcp__)(?:[a-z][a-z0-9_]{0,63}|[a-z][a-z0-9-]{0,39}\\.[A-Za-z0-9_.-]{1,128})$"
                                        },
                                        "additionalProperties": {}
                                      },
                                      "approves": {
                                        "description": "true: the test user says yes to each approval for a tool of one of the deployment's own MCP servers, which in a test plays its tool_results entry or does not run. Absent or false: it says no to every approval. Anything else that waits for a yes is always declined.",
                                        "examples": [
                                          true
                                        ],
                                        "type": "boolean"
                                      }
                                    },
                                    "required": [
                                      "name",
                                      "persona",
                                      "goal",
                                      "success_criteria",
                                      "must_never"
                                    ],
                                    "description": "The scenario as it was played."
                                  },
                                  "verdict": {
                                    "type": "string",
                                    "enum": [
                                      "passed",
                                      "failed",
                                      "error"
                                    ],
                                    "description": "`passed`: every line of success met and nothing it must never do. `failed`: not so. `error`: it could not be played to the end."
                                  },
                                  "reason": {
                                    "type": "string",
                                    "description": "Why, in a sentence or two."
                                  },
                                  "criteria": {
                                    "type": "array",
                                    "items": {
                                      "type": "object",
                                      "properties": {
                                        "criterion": {
                                          "type": "string",
                                          "description": "One line of what a pass looks like."
                                        },
                                        "met": {
                                          "type": "boolean",
                                          "description": "Whether the conversation met it."
                                        },
                                        "evidence": {
                                          "type": "string",
                                          "description": "Why the grader says so, from the conversation."
                                        }
                                      },
                                      "required": [
                                        "criterion",
                                        "met",
                                        "evidence"
                                      ]
                                    },
                                    "description": "Each line of success, graded."
                                  },
                                  "must_never": {
                                    "type": "array",
                                    "items": {
                                      "type": "object",
                                      "properties": {
                                        "rule": {
                                          "type": "string",
                                          "description": "One line of what must never happen."
                                        },
                                        "violated": {
                                          "type": "boolean",
                                          "description": "Whether it happened."
                                        },
                                        "evidence": {
                                          "type": "string",
                                          "description": "Why the grader says so, from the conversation."
                                        }
                                      },
                                      "required": [
                                        "rule",
                                        "violated",
                                        "evidence"
                                      ]
                                    },
                                    "description": "Each thing it must never do, graded."
                                  },
                                  "approvals_asked": {
                                    "type": "array",
                                    "items": {
                                      "type": "object",
                                      "properties": {
                                        "kind": {
                                          "type": "string",
                                          "description": "The kind of ask Bash raised, such as `hands_approval`, `credit_approval` or `tool_permission`."
                                        },
                                        "category": {
                                          "type": "string",
                                          "enum": [
                                            "payment",
                                            "account_action",
                                            "connect_app",
                                            "action",
                                            "custom"
                                          ],
                                          "description": "What it would have done: a `payment`, an `account_action`, `connect_app`, another `action`, or `custom`."
                                        },
                                        "summary": {
                                          "type": "string",
                                          "description": "What it asked to do, in its words."
                                        },
                                        "decision": {
                                          "type": "string",
                                          "enum": [
                                            "denied",
                                            "approved"
                                          ],
                                          "description": "What the test user said. It denies anything that would act for it, so a test never moves money or changes an account; a test with approves: true approves the tools of the deployment's own MCP servers, which a test plays from its tool_results or does not run."
                                        }
                                      },
                                      "required": [
                                        "kind",
                                        "category",
                                        "summary",
                                        "decision"
                                      ]
                                    },
                                    "description": "What Bash asked the test user's yes for, and what it said."
                                  },
                                  "transcript": {
                                    "type": "array",
                                    "items": {
                                      "type": "object",
                                      "properties": {
                                        "role": {
                                          "type": "string",
                                          "enum": [
                                            "customer",
                                            "bash",
                                            "note"
                                          ],
                                          "description": "Who said it: `customer` (the test user), `bash`, or a `note` on what happened (work started, a tool called)."
                                        },
                                        "text": {
                                          "type": "string",
                                          "description": "What was said, or what happened."
                                        }
                                      },
                                      "required": [
                                        "role",
                                        "text"
                                      ]
                                    },
                                    "description": "The conversation, line by line."
                                  },
                                  "conversation_id": {
                                    "anyOf": [
                                      {
                                        "type": "string"
                                      },
                                      {
                                        "type": "null"
                                      }
                                    ],
                                    "description": "The test conversation; null when it never started."
                                  },
                                  "cost_usd": {
                                    "type": "number",
                                    "description": "What playing it cost, in billed US dollars."
                                  }
                                },
                                "required": [
                                  "object",
                                  "scenario_id",
                                  "scenario",
                                  "verdict",
                                  "reason",
                                  "criteria",
                                  "must_never",
                                  "approvals_asked",
                                  "transcript",
                                  "conversation_id",
                                  "cost_usd"
                                ]
                              }
                            }
                          },
                          "required": [
                            "id",
                            "object",
                            "deployment_id",
                            "version",
                            "status",
                            "error_code",
                            "scenario_count",
                            "passed_count",
                            "resumes",
                            "promoted",
                            "became_default",
                            "cost_usd",
                            "created_at",
                            "started_at",
                            "finished_at"
                          ]
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The test run this apply started; null when it started none."
                    },
                    "promote": {
                      "type": "object",
                      "properties": {
                        "when": {
                          "type": "string",
                          "enum": [
                            "after_tests",
                            "now",
                            "no"
                          ],
                          "description": "When it was asked to go live: `after_tests`, `now` or `no`."
                        },
                        "mode": {
                          "type": "string",
                          "enum": [
                            "live",
                            "test"
                          ],
                          "description": "The key's mode: `live` moves `live_version`, `test` moves `draft_version`."
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "promoted",
                            "already",
                            "waiting",
                            "not_promoted"
                          ],
                          "description": "`promoted`: this call moved it. `already`: that mode already runs this version. `waiting`: its tests run first. `not_promoted`: see `code`."
                        },
                        "code": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ],
                          "description": "Why it was not promoted, as an error code; null when you sent `promote=no`. After `promoted` or `already`: the first thing in the file that could not be made in this mode, such as a missing secret. Fix it and apply the file again."
                        },
                        "message": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ],
                          "description": "The same, in a sentence a person can read; null with no `code`."
                        }
                      },
                      "required": [
                        "when",
                        "mode",
                        "status",
                        "code",
                        "message"
                      ],
                      "description": "Whether, and when, the version goes live."
                    },
                    "new_webhooks": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "The webhook endpoint's id."
                          },
                          "url": {
                            "type": "string",
                            "description": "Where its events go."
                          },
                          "secret": {
                            "type": "string",
                            "description": "Its signing secret, shown here once: store it to check each delivery."
                          }
                        },
                        "required": [
                          "id",
                          "url",
                          "secret"
                        ]
                      },
                      "description": "The webhook endpoints this call made, each with its signing secret."
                    },
                    "became_default": {
                      "type": "boolean",
                      "description": "True when this made the deployment the company's default, which it had none of: an ask that names no deployment now reaches it. A promotion that waits for its tests sets it when they pass."
                    }
                  },
                  "required": [
                    "object",
                    "deployment",
                    "version",
                    "changed",
                    "tests",
                    "promote",
                    "new_webhooks",
                    "became_default"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "$schema": {
                    "description": "For editors reading JSON; ignored.",
                    "type": "string",
                    "maxLength": 500
                  },
                  "name": {
                    "type": "string",
                    "pattern": "^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$",
                    "description": "The deployment's name, as in `PUT /v1/deployments/{name}`: lowercase letters, digits and dashes.",
                    "examples": [
                      "trip-rescue"
                    ]
                  },
                  "instructions": {
                    "default": "",
                    "description": "What Bash does here, and how, in plain words: up to 8,000 characters.",
                    "examples": [
                      "You help Tripnest travellers fix broken trips. Always offer two options."
                    ],
                    "type": "string",
                    "maxLength": 8000
                  },
                  "language": {
                    "default": "auto",
                    "description": "The language Bash speaks: a tag such as `en`, `hi` or `pt-BR`, or `auto` to follow each user.",
                    "examples": [
                      "hi"
                    ],
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 35
                  },
                  "model": {
                    "default": "default",
                    "description": "`default`, or a model id from `GET /v1/models`.",
                    "examples": [
                      "default"
                    ],
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100
                  },
                  "apps": {
                    "default": "all",
                    "description": "The apps its users may connect: `all`, or a list.",
                    "examples": [
                      [
                        "gmail",
                        "google-calendar"
                      ]
                    ],
                    "anyOf": [
                      {
                        "type": "string",
                        "const": "all"
                      },
                      {
                        "maxItems": 200,
                        "type": "array",
                        "items": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 64
                        }
                      }
                    ]
                  },
                  "tools": {
                    "default": [],
                    "description": "Tools Bash may call: MCP servers by their URL, and functions your own code answers. At most 50.",
                    "examples": [
                      [
                        {
                          "function": "get_booking",
                          "description": "A booking by its PNR",
                          "input": {
                            "pnr": "string"
                          },
                          "read_only": true
                        },
                        {
                          "mcp": "https://mcp.example.com/travel",
                          "require_approval": [
                            "book_flight"
                          ]
                        }
                      ]
                    ],
                    "maxItems": 50,
                    "type": "array",
                    "items": {
                      "anyOf": [
                        {
                          "type": "object",
                          "properties": {
                            "mcp": {
                              "type": "string",
                              "maxLength": 2048,
                              "format": "uri",
                              "description": "The server's public https URL. The first file that names it registers it, and later files find it by it.",
                              "examples": [
                                "https://mcp.example.com/travel"
                              ]
                            },
                            "name": {
                              "description": "How the server is shown. Absent: the URL's host.",
                              "examples": [
                                "Travel desk"
                              ],
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 80
                            },
                            "auth": {
                              "description": "One company secret, written `${NAME}`: sent as `Authorization: Bearer` and its value.",
                              "examples": [
                                "${TRAVEL_MCP_TOKEN}"
                              ],
                              "type": "string",
                              "pattern": "^\\$\\{(?:(?:secret|user_secret):)?[A-Z][A-Z0-9_]{0,63}\\}$"
                            },
                            "headers": {
                              "description": "Other headers to send. A value may carry `${NAME}` (a company secret) or `${user_secret:NAME}` (each user's own).",
                              "examples": [
                                {
                                  "X-Agency": "${user_secret:AGENCY_ID}"
                                }
                              ],
                              "type": "object",
                              "propertyNames": {
                                "type": "string",
                                "pattern": "^[A-Za-z0-9-]{1,64}$"
                              },
                              "additionalProperties": {
                                "type": "string",
                                "minLength": 1,
                                "maxLength": 2048
                              }
                            },
                            "deny": {
                              "description": "Tools of this server Bash never calls. With `require_approval`, it is this version's own tool policy (`mcp_tool_policy`), on top of the server's floor.",
                              "examples": [
                                [
                                  "refund_booking"
                                ]
                              ],
                              "maxItems": 200,
                              "type": "array",
                              "items": {
                                "type": "string",
                                "pattern": "^[A-Za-z0-9_.-]{1,128}$"
                              }
                            },
                            "require_approval": {
                              "description": "Tools of this server that always wait for the person's yes, even one the server marks read-only.",
                              "examples": [
                                [
                                  "book_flight"
                                ]
                              ],
                              "maxItems": 200,
                              "type": "array",
                              "items": {
                                "type": "string",
                                "pattern": "^[A-Za-z0-9_.-]{1,128}$"
                              }
                            },
                            "run_without_asking": {
                              "description": "Tools of this server Bash runs without waiting for the person's yes. Every other tool waits for it, unless the server marks the tool read-only (readOnlyHint).",
                              "examples": [
                                [
                                  "points_balance"
                                ]
                              ],
                              "maxItems": 200,
                              "type": "array",
                              "items": {
                                "type": "string",
                                "pattern": "^[A-Za-z0-9_.-]{1,128}$"
                              }
                            }
                          },
                          "required": [
                            "mcp"
                          ],
                          "additionalProperties": false,
                          "description": "An MCP server Bash may call, by its URL. Each of its tools waits for the person's yes before it runs, unless the server marks it read-only or `run_without_asking` lists it."
                        },
                        {
                          "type": "object",
                          "properties": {
                            "function": {
                              "type": "string",
                              "pattern": "^(?!mcp__)[a-z][a-z0-9_]{0,63}$",
                              "description": "The tool's name: lowercase letters, digits and underscores, starting with a letter.",
                              "examples": [
                                "get_booking"
                              ]
                            },
                            "description": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 1024,
                              "description": "What the tool does, so Bash knows when to call it.",
                              "examples": [
                                "A booking by its PNR"
                              ]
                            },
                            "input": {
                              "default": {},
                              "description": "Its arguments: shorthand such as `{ pnr: string }`, with `[]` for a list and `?` for optional, or JSON Schema.",
                              "examples": [
                                {
                                  "pnr": "string",
                                  "seats": "integer?"
                                }
                              ],
                              "type": "object",
                              "propertyNames": {
                                "type": "string"
                              },
                              "additionalProperties": {}
                            },
                            "timeout_s": {
                              "description": "Seconds Bash waits for your answer, 5 to 600. Absent: 120.",
                              "examples": [
                                30
                              ],
                              "type": "integer",
                              "minimum": 5,
                              "maximum": 600
                            },
                            "read_only": {
                              "description": "true when the tool changes nothing, such as a lookup: Bash calls it without waiting for the person's yes. Absent: false, so it waits.",
                              "examples": [
                                true
                              ],
                              "type": "boolean"
                            },
                            "run_without_asking": {
                              "description": "true when the tool changes something that needs no yes: Bash calls it without waiting for the person's yes. Absent: false, so it waits.",
                              "examples": [
                                true
                              ],
                              "type": "boolean"
                            }
                          },
                          "required": [
                            "function",
                            "description"
                          ],
                          "additionalProperties": false,
                          "description": "A tool your own code answers: Bash's call reaches you as an interaction of type `tool_call`. It waits for the person's yes first, unless `read_only` or `run_without_asking` is true."
                        }
                      ]
                    }
                  },
                  "skills": {
                    "default": [],
                    "description": "Skills Bash may use: a local folder of skills, or a list of folders, company skills by id and skills Bash has by name. At most 100.",
                    "examples": [
                      [
                        "./skills/refunds",
                        {
                          "name": "pdf"
                        }
                      ]
                    ],
                    "anyOf": [
                      {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 500
                      },
                      {
                        "maxItems": 100,
                        "type": "array",
                        "items": {
                          "anyOf": [
                            {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 500,
                              "description": "A local folder: the CLI and the SDKs upload it."
                            },
                            {
                              "type": "object",
                              "properties": {
                                "id": {
                                  "type": "string",
                                  "pattern": "^skl_",
                                  "description": "A company skill's `skl_` id."
                                }
                              },
                              "required": [
                                "id"
                              ],
                              "additionalProperties": false,
                              "description": "A company skill, by its id."
                            },
                            {
                              "type": "object",
                              "properties": {
                                "name": {
                                  "type": "string",
                                  "pattern": "^[a-z0-9][a-z0-9-]{0,63}$",
                                  "description": "The skill's name."
                                }
                              },
                              "required": [
                                "name"
                              ],
                              "additionalProperties": false,
                              "description": "A skill Bash already has, by its name."
                            }
                          ]
                        }
                      }
                    ]
                  },
                  "knowledge": {
                    "default": [],
                    "description": "What Bash reads before it answers: a local folder or file, or a list of them and notebooks by id. At most 50.",
                    "examples": [
                      "./policies"
                    ],
                    "anyOf": [
                      {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 500
                      },
                      {
                        "maxItems": 50,
                        "type": "array",
                        "items": {
                          "anyOf": [
                            {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 500,
                              "description": "A local folder or file: the CLI and the SDKs upload it into a notebook."
                            },
                            {
                              "type": "object",
                              "properties": {
                                "notebook": {
                                  "type": "string",
                                  "pattern": "^nb_",
                                  "description": "The notebook's `nb_` id."
                                }
                              },
                              "required": [
                                "notebook"
                              ],
                              "additionalProperties": false,
                              "description": "A notebook, by its id."
                            }
                          ]
                        }
                      }
                    ]
                  },
                  "approvals": {
                    "default": [
                      "payment",
                      "booking",
                      "cancellation"
                    ],
                    "description": "What Bash asks the person before doing. A system approval enforces what `approvals` lists for your own functions and your MCP servers' tools that wait for a yes; in a browser or a connected app, Bash is instructed to ask.",
                    "examples": [
                      [
                        "payment",
                        "booking",
                        "cancellation",
                        "send_email"
                      ]
                    ],
                    "maxItems": 6,
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "payment",
                        "booking",
                        "cancellation",
                        "send_email",
                        "publish",
                        "delete"
                      ]
                    }
                  },
                  "memory": {
                    "description": "What Bash remembers about each user: `vestra` (Bash keeps it), `customer` (your side keeps it) or `none`. Absent: the company's default.",
                    "examples": [
                      "vestra"
                    ],
                    "type": "string",
                    "enum": [
                      "vestra",
                      "customer",
                      "none"
                    ]
                  },
                  "computer": {
                    "description": "Bash's computer, ready before the first task: a setup script, repositories, environment variables and files.",
                    "examples": [
                      {
                        "setup": "./setup.sh",
                        "env": {
                          "REGION": "ap-south-1"
                        }
                      }
                    ],
                    "type": "object",
                    "properties": {
                      "setup": {
                        "description": "A setup script, run once on each computer. Name a local file: the CLI and the SDKs read it and send its text.",
                        "examples": [
                          "./setup.sh"
                        ],
                        "type": "string",
                        "maxLength": 20000
                      },
                      "repos": {
                        "description": "Repositories cloned onto the computer, at most 10.",
                        "examples": [
                          [
                            "github.com/acme/booking-tools"
                          ]
                        ],
                        "maxItems": 10,
                        "type": "array",
                        "items": {
                          "anyOf": [
                            {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 2048,
                              "description": "`github.com/owner/repo`, or its https URL: branch main, cloned into a folder named after the repo."
                            },
                            {
                              "type": "object",
                              "properties": {
                                "url": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 2048,
                                  "description": "The repository's address."
                                },
                                "ref": {
                                  "description": "The branch, tag or commit. Absent: main.",
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 200
                                },
                                "path": {
                                  "description": "The folder to clone into. Absent: the repository's name.",
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 200
                                },
                                "token": {
                                  "description": "A token kept as a company secret, written `${NAME}`: never the raw value.",
                                  "type": "string",
                                  "pattern": "^\\$\\{(?:(?:secret|user_secret):)?[A-Z][A-Z0-9_]{0,63}\\}$"
                                }
                              },
                              "required": [
                                "url"
                              ],
                              "additionalProperties": false,
                              "description": "A repository with its branch, folder or token."
                            }
                          ]
                        }
                      },
                      "env": {
                        "description": "Environment variables. A credential is `${NAME}`, never a raw value.",
                        "examples": [
                          {
                            "REGION": "ap-south-1",
                            "BOOKING_TOKEN": "${BOOKING_TOKEN}"
                          }
                        ],
                        "type": "object",
                        "propertyNames": {
                          "type": "string",
                          "pattern": "^[A-Z_][A-Z0-9_]*$"
                        },
                        "additionalProperties": {
                          "type": "string",
                          "maxLength": 4096
                        }
                      },
                      "files": {
                        "description": "Files uploaded with `POST /v1/files`, placed on the computer.",
                        "examples": [
                          [
                            {
                              "file_id": "file_8f2k",
                              "path": "data/fares.csv"
                            }
                          ]
                        ],
                        "maxItems": 50,
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "file_id": {
                              "type": "string",
                              "pattern": "^file_",
                              "description": "The file's `file_` id."
                            },
                            "path": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 200,
                              "description": "Where it goes on the computer."
                            }
                          },
                          "required": [
                            "file_id",
                            "path"
                          ],
                          "additionalProperties": false
                        }
                      }
                    },
                    "additionalProperties": false
                  },
                  "browser": {
                    "description": "The sites a browser fetch may open, and the pages the browser never opens or acts on. Absent: a fetch opens nothing, and no page is closed.",
                    "examples": [
                      {
                        "allowed_domains": [
                          "ixigo.com"
                        ],
                        "blocked_paths": [
                          "ixigo.com/payments/"
                        ]
                      }
                    ],
                    "type": "object",
                    "properties": {
                      "allowed_domains": {
                        "description": "The sites it may open, as bare host names: `ixigo.com` also allows `www.ixigo.com`. Up to 20.",
                        "minItems": 1,
                        "maxItems": 20,
                        "type": "array",
                        "items": {
                          "type": "string",
                          "maxLength": 253,
                          "pattern": "^(?=.{1,253}$)(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\\.)+[a-z][a-z0-9-]{0,61}[a-z0-9]$"
                        }
                      },
                      "blocked_paths": {
                        "description": "Pages the browser never opens or acts on, as a site and the start of a path, such as `ixigo.com/payments/`. Up to 20.",
                        "minItems": 1,
                        "maxItems": 20,
                        "type": "array",
                        "items": {
                          "type": "string",
                          "maxLength": 300,
                          "pattern": "^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\\.)+[a-z][a-z0-9-]{0,61}[a-z0-9]\\/[^\\s?#]*$"
                        }
                      }
                    },
                    "additionalProperties": false
                  },
                  "routines": {
                    "default": [],
                    "description": "Jobs Bash runs on a schedule or on a call, for your company or for each user. At most 50.",
                    "examples": [
                      [
                        {
                          "ask": "Check today's trips for delays",
                          "every": "weekday at 08:00",
                          "for": "each customer"
                        }
                      ]
                    ],
                    "maxItems": 50,
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "name": {
                          "description": "Its name, which finds the routine again on the next apply. Absent: the start of `ask`.",
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 200
                        },
                        "ask": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 8000,
                          "description": "What Bash does on each run, in plain words."
                        },
                        "every": {
                          "description": "When it runs, in plain words: `weekday at 08:00`, `mon, wed, fri at 18:30`, `30 minutes`, `month on the 1st at 09:00`. Give one of `every`, `schedule` or `on`.",
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 100
                        },
                        "schedule": {
                          "description": "When it runs, as cron.",
                          "type": "object",
                          "properties": {
                            "cron": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 120,
                              "description": "A cron expression: `0 7 * * *` runs at 7:00 every day."
                            },
                            "timezone": {
                              "description": "The zone the cron is read in, an IANA name such as `Asia/Kolkata`.",
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 64
                            }
                          },
                          "required": [
                            "cron"
                          ],
                          "additionalProperties": false
                        },
                        "on": {
                          "description": "`call`: it runs whenever your system posts to its `trigger_url`.",
                          "type": "string",
                          "const": "call"
                        },
                        "filters": {
                          "description": "With `on: call`, what a call's payload must match for the routine to run.",
                          "type": "object",
                          "propertyNames": {
                            "type": "string"
                          },
                          "additionalProperties": {}
                        },
                        "timezone": {
                          "description": "The zone `every` is read in, an IANA name. Absent: each user's own (or your company's own Bash's), then UTC.",
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 64
                        },
                        "for": {
                          "type": "string",
                          "enum": [
                            "us",
                            "each customer"
                          ],
                          "description": "`us`: your company's own Bash. `each customer`: a copy for every user, made the first time they talk to Bash here."
                        },
                        "enabled": {
                          "description": "false keeps the routine but stops its runs. A routine for each user is on while it is in the file.",
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "ask",
                        "for"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "limits": {
                    "default": {
                      "per_task_usd": 2
                    },
                    "description": "What one task may spend.",
                    "examples": [
                      {
                        "per_task_usd": 5
                      }
                    ],
                    "type": "object",
                    "properties": {
                      "per_task_usd": {
                        "default": 2,
                        "description": "The most one task may spend, in dollars: above 0, at most 100. Absent: 2.",
                        "type": "number",
                        "exclusiveMinimum": 0,
                        "maximum": 100
                      }
                    },
                    "additionalProperties": false
                  },
                  "tests": {
                    "default": [],
                    "description": "Tests each new version runs before it is promoted. At most 20.",
                    "examples": [
                      [
                        {
                          "name": "Bag allowance",
                          "ask": "How many kilos can I take on booking TN-48213?",
                          "expect": "Says 7 kg of cabin baggage.",
                          "tool_results": {
                            "get_booking": {
                              "cabin_kg": 7
                            }
                          }
                        }
                      ]
                    ],
                    "maxItems": 20,
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "name": {
                          "description": "Its name, which finds the test again on the next apply. Absent: the start of `ask`.",
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 120
                        },
                        "ask": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 2000,
                          "description": "What the test user wants, in their words."
                        },
                        "expect": {
                          "anyOf": [
                            {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 500
                            },
                            {
                              "minItems": 1,
                              "maxItems": 12,
                              "type": "array",
                              "items": {
                                "type": "string",
                                "minLength": 1,
                                "maxLength": 500
                              }
                            }
                          ],
                          "description": "What a pass looks like: one line, or up to 12."
                        },
                        "never": {
                          "description": "What must never happen: one line, or up to 12.",
                          "anyOf": [
                            {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 500
                            },
                            {
                              "maxItems": 12,
                              "type": "array",
                              "items": {
                                "type": "string",
                                "minLength": 1,
                                "maxLength": 500
                              }
                            }
                          ]
                        },
                        "persona": {
                          "description": "Who the test user is. Absent: a person who uses the company's app.",
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 2000
                        },
                        "tool_results": {
                          "description": "What each tool answers in this test: a function tool by its name, and a tool of an MCP server as <server>.<tool> (the server's slug, from its URL's host), since a test never runs one for real unless the server marks it read-only. A tool with none answers an error.",
                          "type": "object",
                          "propertyNames": {
                            "type": "string",
                            "pattern": "^(?!mcp__)(?:[a-z][a-z0-9_]{0,63}|[a-z][a-z0-9-]{0,39}\\.[A-Za-z0-9_.-]{1,128})$"
                          },
                          "additionalProperties": {}
                        },
                        "approves": {
                          "description": "true: the test user says yes to each approval for a tool of your MCP server, which plays its `tool_results` entry or does not run, so the test can check what Bash does after a yes. Absent or false: it says no to every approval. Anything else that waits for a yes is always declined.",
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "ask",
                        "expect"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "webhooks": {
                    "default": {},
                    "description": "Where events go: each https URL, with the events it gets, or `*` for every one.",
                    "examples": [
                      {
                        "https://example.com/vestra": [
                          "task.completed",
                          "interaction.created"
                        ]
                      }
                    ],
                    "type": "object",
                    "propertyNames": {
                      "type": "string",
                      "maxLength": 2048,
                      "format": "uri"
                    },
                    "additionalProperties": {
                      "minItems": 1,
                      "maxItems": 40,
                      "type": "array",
                      "items": {
                        "anyOf": [
                          {
                            "type": "string",
                            "enum": [
                              "message.completed",
                              "task.started",
                              "task.completed",
                              "task.failed",
                              "task.stopped",
                              "interaction.created",
                              "interaction.resolved",
                              "interaction.expired",
                              "session.started",
                              "session.ended",
                              "file.created",
                              "routine.fired",
                              "usage.threshold_reached",
                              "usage.cap_reached",
                              "conversation.status",
                              "user.created",
                              "user.deleted",
                              "connection.completed",
                              "connection.failed",
                              "connection.removed",
                              "memory.observed",
                              "batch.completed",
                              "deployment.version_created",
                              "deployment.promoted",
                              "deployment.rolled_back",
                              "test_run.completed",
                              "key.created",
                              "key.revoked"
                            ],
                            "description": "An event a webhook carries: every event of the catalog but the six that ride only the stream (message.delta, task.progress, usage.updated, screen.control, error and ping).",
                            "examples": [
                              "task.completed"
                            ]
                          },
                          {
                            "type": "string",
                            "const": "*"
                          }
                        ],
                        "description": "An event the endpoint wants, by its type, or * for every event a webhook carries.",
                        "examples": [
                          "task.completed"
                        ]
                      }
                    }
                  }
                },
                "required": [
                  "name"
                ],
                "additionalProperties": false
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "patchDeploymentsByDeploymentId",
        "summary": "Rename, describe or archive it.",
        "tags": [
          "Deployments"
        ],
        "x-vestra-line": "deploy",
        "x-vestra-scope": "setup",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "deployment_id",
            "in": "path",
            "required": true,
            "description": "The deployment's id (`dep_...`). The /v1/deployments routes also take its name.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "The deployment's id.",
                      "examples": [
                        "dep_8f2k"
                      ]
                    },
                    "object": {
                      "type": "string",
                      "const": "deployment",
                      "description": "Always `deployment`."
                    },
                    "name": {
                      "type": "string",
                      "description": "Its name, as people read it."
                    },
                    "slug": {
                      "type": "string",
                      "description": "Its name in URLs and refs: send it where a route takes `{deployment_id}`.",
                      "examples": [
                        "trip-rescue"
                      ]
                    },
                    "description": {
                      "type": "string",
                      "description": "What it is for; empty when none was given."
                    },
                    "base": {
                      "type": "string",
                      "const": "bash",
                      "description": "What it is built on: always `bash`."
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "active",
                        "archived"
                      ],
                      "description": "`active`, or `archived` (put away: no new conversation or version reaches it)."
                    },
                    "draft_version": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991,
                      "description": "The version test keys run. A new save moves it there; a promote with a test key moves it to the version named, older ones included."
                    },
                    "live_version": {
                      "anyOf": [
                        {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The version live keys run; null until one is promoted."
                    },
                    "created_at": {
                      "type": "string",
                      "description": "When it was made, as an ISO 8601 date and time in UTC."
                    },
                    "updated_at": {
                      "type": "string",
                      "description": "When it last changed, as an ISO 8601 date and time in UTC."
                    }
                  },
                  "required": [
                    "id",
                    "object",
                    "name",
                    "slug",
                    "description",
                    "base",
                    "status",
                    "draft_version",
                    "live_version",
                    "created_at",
                    "updated_at"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "description": "A new name, 1 to 120 characters.",
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 120
                  },
                  "description": {
                    "description": "A new description, up to 2,000 characters.",
                    "type": "string",
                    "maxLength": 2000
                  },
                  "status": {
                    "description": "`archived` puts it away: no new conversation or version reaches it. `active` brings it back.",
                    "type": "string",
                    "enum": [
                      "active",
                      "archived"
                    ]
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/deployments/{deployment_id}/versions": {
      "post": {
        "operationId": "postDeploymentsByDeploymentIdVersions",
        "summary": "Save a new version: instructions, language, MCP servers and this version's own tool policy for them (mcp_tool_policy, on top of each server's floor), allowed apps, approval rules, model, memory mode, notebooks, limits per task.",
        "tags": [
          "Deployments"
        ],
        "x-vestra-line": "deploy",
        "x-vestra-scope": "setup",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "deployment_id",
            "in": "path",
            "required": true,
            "description": "The deployment's id (`dep_...`). The /v1/deployments routes also take its name.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 255
            },
            "description": "Send the same key to retry this call safely for 24 hours."
          }
        ],
        "responses": {
          "201": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "type": "string",
                      "const": "deployment_version",
                      "description": "Always `deployment_version`."
                    },
                    "deployment_id": {
                      "type": "string",
                      "description": "The deployment's id.",
                      "examples": [
                        "dep_8f2k"
                      ]
                    },
                    "version": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991,
                      "description": "A version number: 1 is the first, and each save adds one."
                    },
                    "manifest": {
                      "type": "object",
                      "properties": {
                        "base": {
                          "default": "bash",
                          "description": "What the deployment is built on: always `bash`.",
                          "type": "string",
                          "const": "bash"
                        },
                        "instructions": {
                          "default": "",
                          "description": "What Bash does here, and how, in plain words, up to 8,000 characters. Empty by default.",
                          "type": "string",
                          "maxLength": 8000
                        },
                        "language": {
                          "default": "auto",
                          "description": "The language Bash speaks: a tag such as `en`, `hi` or `pt-BR`, or `auto` (the default) to follow each user.",
                          "type": "string"
                        },
                        "mcp_servers": {
                          "default": [],
                          "description": "The MCP servers Bash may call, by their `mcp_` ids (POST /v1/mcp-servers).",
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "mcp_tool_policy": {
                          "description": "This version's own tool policy for its MCP servers, on top of each server's floor. Absent (every version saved before it): each server's own policy alone.",
                          "maxItems": 50,
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "server": {
                                "type": "string",
                                "description": "The MCP server, by its `mcp_` id, one `mcp_servers` lists."
                              },
                              "deny": {
                                "default": [],
                                "description": "Tools of the server this version never calls, on top of the server's own floor.",
                                "maxItems": 200,
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "pattern": "^[A-Za-z0-9_.-]{1,128}$"
                                }
                              },
                              "require_approval": {
                                "default": [],
                                "description": "Tools of the server that wait for the person's yes in this version, on top of the server's own floor.",
                                "maxItems": 200,
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "pattern": "^[A-Za-z0-9_.-]{1,128}$"
                                }
                              },
                              "run_without_asking": {
                                "description": "Tools of the server this version runs without waiting for the person's yes. Every other tool of the server waits for it, unless the server marks the tool read-only (readOnlyHint).",
                                "maxItems": 200,
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "pattern": "^[A-Za-z0-9_.-]{1,128}$"
                                }
                              }
                            },
                            "required": [
                              "server",
                              "deny",
                              "require_approval"
                            ]
                          }
                        },
                        "apps": {
                          "default": {
                            "allow": "all"
                          },
                          "description": "Which apps its users may connect.",
                          "type": "object",
                          "properties": {
                            "allow": {
                              "default": "all",
                              "description": "The apps its users may connect: `all` (the default), or a list such as `[\"gmail\"]`.",
                              "anyOf": [
                                {
                                  "type": "string",
                                  "const": "all"
                                },
                                {
                                  "type": "array",
                                  "items": {
                                    "type": "string"
                                  }
                                }
                              ]
                            }
                          },
                          "required": [
                            "allow"
                          ]
                        },
                        "approvals": {
                          "default": {
                            "always": [
                              "payment",
                              "booking",
                              "cancellation"
                            ]
                          },
                          "description": "What Bash asks the person before doing.",
                          "type": "object",
                          "properties": {
                            "always": {
                              "default": [
                                "payment",
                                "booking",
                                "cancellation"
                              ],
                              "description": "What Bash asks the person before doing: any of `payment`, `booking`, `cancellation`, `send_email`, `publish` and `delete`. Default the first three. A system approval enforces what `approvals` lists for your own functions and your MCP servers' tools that wait for a yes; in a browser or a connected app, Bash is instructed to ask.",
                              "type": "array",
                              "items": {
                                "type": "string",
                                "enum": [
                                  "payment",
                                  "booking",
                                  "cancellation",
                                  "send_email",
                                  "publish",
                                  "delete"
                                ]
                              }
                            }
                          },
                          "required": [
                            "always"
                          ]
                        },
                        "model": {
                          "default": "default",
                          "description": "`default` (the default), or a model id from GET /v1/models.",
                          "type": "string"
                        },
                        "memory": {
                          "default": {},
                          "description": "What Bash remembers about each user here.",
                          "type": "object",
                          "properties": {
                            "mode": {
                              "description": "`vestra`, `customer` or `none`. Absent: the company's `memory_mode`.",
                              "type": "string",
                              "enum": [
                                "vestra",
                                "customer",
                                "none"
                              ]
                            }
                          }
                        },
                        "notebooks": {
                          "default": [],
                          "description": "What Bash reads before it answers: notebooks, by their `nb_` ids.",
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "skills": {
                          "default": [],
                          "description": "Skills Bash may use: company skills by their `skl_` ids, or skills Bash already has, by name.",
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "tools": {
                          "default": [],
                          "description": "Tools your own code answers: Bash's call reaches you as an interaction of type `tool_call`, after the person's yes unless the tool is marked `read_only` or `run_without_asking`.",
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "name": {
                                "type": "string",
                                "pattern": "^(?!mcp__)[a-z][a-z0-9_]{0,63}$",
                                "description": "The tool's name: lowercase letters, digits and underscores, starting with a letter, up to 64.",
                                "examples": [
                                  "get_booking"
                                ]
                              },
                              "description": {
                                "type": "string",
                                "minLength": 1,
                                "maxLength": 1024,
                                "description": "What the tool does, so Bash knows when to call it, up to 1024 characters.",
                                "examples": [
                                  "A booking by its PNR"
                                ]
                              },
                              "input_schema": {
                                "type": "object",
                                "propertyNames": {
                                  "type": "string"
                                },
                                "additionalProperties": {},
                                "description": "Its arguments, as JSON Schema with `type: object`. Bash's call fills them in.",
                                "examples": [
                                  {
                                    "type": "object",
                                    "properties": {
                                      "pnr": {
                                        "type": "string"
                                      }
                                    },
                                    "required": [
                                      "pnr"
                                    ]
                                  }
                                ]
                              },
                              "timeout_s": {
                                "default": 120,
                                "description": "Seconds Bash waits for your answer, 5 to 600. Default 120; after it, the call expires.",
                                "type": "integer",
                                "minimum": 5,
                                "maximum": 600
                              },
                              "read_only": {
                                "description": "true: the tool changes nothing (a lookup), so Bash calls it without waiting for the person's yes. Absent: false.",
                                "type": "boolean"
                              },
                              "run_without_asking": {
                                "description": "true: the tool changes something that needs no yes, so Bash calls it without waiting for the person's yes. Absent: false.",
                                "type": "boolean"
                              }
                            },
                            "required": [
                              "name",
                              "description",
                              "input_schema",
                              "timeout_s"
                            ]
                          }
                        },
                        "environment": {
                          "description": "Bash's computer, ready before the first task: a setup script, environment variables, repositories and files. Absent: a plain computer.",
                          "type": "object",
                          "properties": {
                            "setup_script": {
                              "description": "A shell script run once on each computer before its first task, and again when the environment changes, up to 20,000 characters. Absent: none.",
                              "type": "string",
                              "maxLength": 20000
                            },
                            "env": {
                              "default": {},
                              "description": "Environment variables on the computer, by name. A credential is `${secret:NAME}`, filled in from your secrets, never a raw value.",
                              "examples": [
                                {
                                  "REGION": "ap-south-1"
                                }
                              ],
                              "type": "object",
                              "propertyNames": {
                                "type": "string",
                                "pattern": "^[A-Z_][A-Z0-9_]*$"
                              },
                              "additionalProperties": {
                                "type": "string"
                              }
                            },
                            "repos": {
                              "default": [],
                              "description": "Repositories cloned onto the computer.",
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "url": {
                                    "type": "string",
                                    "format": "uri",
                                    "description": "The repository's https URL."
                                  },
                                  "ref": {
                                    "default": "main",
                                    "description": "The branch, tag or commit to check out. Default `main`.",
                                    "type": "string"
                                  },
                                  "path": {
                                    "type": "string",
                                    "description": "The folder on the computer it is cloned into."
                                  },
                                  "token": {
                                    "description": "A token to clone it with, as `${secret:NAME}`. Absent: a public repository.",
                                    "type": "string"
                                  }
                                },
                                "required": [
                                  "url",
                                  "ref",
                                  "path"
                                ]
                              }
                            },
                            "files": {
                              "default": [],
                              "description": "Files placed on the computer.",
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "file_id": {
                                    "type": "string",
                                    "description": "A file you uploaded with POST /v1/files, by its `file_` id."
                                  },
                                  "path": {
                                    "type": "string",
                                    "description": "Where it goes on the computer."
                                  }
                                },
                                "required": [
                                  "file_id",
                                  "path"
                                ]
                              }
                            }
                          },
                          "required": [
                            "env",
                            "repos",
                            "files"
                          ]
                        },
                        "browser": {
                          "description": "The sites a browser fetch may open, and the pages the browser never opens or acts on. Absent: a fetch opens nothing, and no page is closed.",
                          "type": "object",
                          "properties": {
                            "allowed_domains": {
                              "description": "The sites a browser fetch may open, as bare host names such as `ixigo.com`, which also allows `www.ixigo.com`. Up to 20. Absent: a browser fetch opens nothing.",
                              "examples": [
                                [
                                  "ixigo.com"
                                ]
                              ],
                              "minItems": 1,
                              "maxItems": 20,
                              "type": "array",
                              "items": {
                                "type": "string",
                                "maxLength": 253,
                                "pattern": "^(?=.{1,253}$)(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\\.)+[a-z][a-z0-9-]{0,61}[a-z0-9]$"
                              }
                            },
                            "blocked_paths": {
                              "description": "Pages the browser never opens or acts on, as a site and the start of a path, such as `ixigo.com/payments/`. Enforced in code for a browser fetch (403 page_blocked) and Bash's own browser tools. Up to 20.",
                              "examples": [
                                [
                                  "ixigo.com/payments/"
                                ]
                              ],
                              "minItems": 1,
                              "maxItems": 20,
                              "type": "array",
                              "items": {
                                "type": "string",
                                "maxLength": 300,
                                "pattern": "^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\\.)+[a-z][a-z0-9-]{0,61}[a-z0-9]\\/[^\\s?#]*$"
                              }
                            }
                          }
                        },
                        "routines": {
                          "default": [],
                          "description": "Not used: a version holds no routines. Write them in vestra.yaml, or make them with POST /v1/routines.",
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "name": {
                                "type": "string",
                                "description": "The routine's name."
                              },
                              "schedule": {
                                "type": "string",
                                "description": "When it runs."
                              },
                              "message": {
                                "type": "string",
                                "description": "What it asks."
                              }
                            },
                            "required": [
                              "name",
                              "schedule",
                              "message"
                            ]
                          }
                        },
                        "limits": {
                          "default": {
                            "spend_per_task_usd": 2
                          },
                          "description": "What one piece of work may spend. There is no time limit.",
                          "type": "object",
                          "properties": {
                            "spend_per_task_usd": {
                              "default": 2,
                              "description": "The most one piece of work may spend, in US dollars, above 0 and at most 100. Default 2.",
                              "type": "number",
                              "exclusiveMinimum": 0,
                              "maximum": 100
                            }
                          },
                          "required": [
                            "spend_per_task_usd"
                          ]
                        }
                      },
                      "required": [
                        "base",
                        "instructions",
                        "language",
                        "mcp_servers",
                        "apps",
                        "approvals",
                        "model",
                        "memory",
                        "notebooks",
                        "skills",
                        "tools",
                        "routines",
                        "limits"
                      ],
                      "description": "The version's settings, every default filled in."
                    },
                    "manifest_sha256": {
                      "type": "string",
                      "description": "A hash of the settings: two versions with the same hash run the same."
                    },
                    "skill_pins": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "skill": {
                            "type": "string",
                            "description": "The company skill, by its `skl_` id."
                          },
                          "slug": {
                            "type": "string",
                            "description": "The skill's name."
                          },
                          "pressing_sha256": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "The content hash of the skill's version when this version was saved: the one it runs. Null when none was recorded."
                          }
                        },
                        "required": [
                          "skill",
                          "slug",
                          "pressing_sha256"
                        ]
                      },
                      "description": "The company skills this version runs, each at the version of the skill current when it was saved."
                    },
                    "note": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The note it was saved with; null when none."
                    },
                    "created_by": {
                      "type": "string",
                      "description": "Who saved it: a key's id (`key_...`), `console` (a person in the console), `client` (a session token from your app) or `interview` (the draft the interview wrote)."
                    },
                    "created_at": {
                      "type": "string",
                      "description": "When it was saved, as an ISO 8601 date and time in UTC."
                    },
                    "is_draft": {
                      "type": "boolean",
                      "description": "True when test keys run this version."
                    },
                    "is_live": {
                      "type": "boolean",
                      "description": "True when live keys run it."
                    },
                    "test_verdict": {
                      "description": "Its latest test run's verdict: `passed`, `failed`, or `none` (never tested). Only when you read one version (`GET .../versions/{version}`); absent in the list.",
                      "type": "string",
                      "enum": [
                        "passed",
                        "failed",
                        "none"
                      ]
                    },
                    "interview": {
                      "description": "The interview's closing words, on the version the interview saved; absent on every other version.",
                      "type": "object",
                      "properties": {
                        "summary": {
                          "type": "string",
                          "description": "What the draft sets Bash up to do, in the interview's words."
                        },
                        "tools": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "name": {
                                "type": "string",
                                "description": "The tool's name."
                              },
                              "description": {
                                "type": "string",
                                "description": "What it does."
                              }
                            },
                            "required": [
                              "name",
                              "description"
                            ]
                          },
                          "description": "The tools the file declares that your own code answers."
                        },
                        "per_task_usd": {
                          "type": "number",
                          "description": "The spending cap per piece of work, in US dollars."
                        },
                        "per_task_usd_is_default": {
                          "type": "boolean",
                          "description": "True when that cap is the default, 2, because the file left it."
                        },
                        "tests": {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991,
                          "description": "How many starter tests the file holds."
                        },
                        "next_steps": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "What to do next, one plain line each, in order."
                        }
                      },
                      "required": [
                        "summary",
                        "tools",
                        "per_task_usd",
                        "per_task_usd_is_default",
                        "tests",
                        "next_steps"
                      ]
                    }
                  },
                  "required": [
                    "object",
                    "deployment_id",
                    "version",
                    "manifest",
                    "manifest_sha256",
                    "skill_pins",
                    "note",
                    "created_by",
                    "created_at",
                    "is_draft",
                    "is_live"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "manifest": {
                    "type": "object",
                    "propertyNames": {
                      "type": "string"
                    },
                    "additionalProperties": {},
                    "description": "The version's settings as a manifest: `instructions`, `language`, `model`, `mcp_servers`, `mcp_tool_policy`, `apps`, `approvals`, `memory`, `notebooks`, `skills`, `tools`, `environment`, `browser` and `limits`. A field left out takes its default."
                  },
                  "note": {
                    "description": "A note on this version, up to 500 characters, such as what changed.",
                    "examples": [
                      "Adds the refund tool."
                    ],
                    "type": "string",
                    "maxLength": 500
                  }
                },
                "required": [
                  "manifest"
                ]
              }
            }
          }
        }
      },
      "get": {
        "operationId": "getDeploymentsByDeploymentIdVersions",
        "summary": "Every version.",
        "tags": [
          "Deployments"
        ],
        "x-vestra-line": "deploy",
        "x-vestra-scope": "setup",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "deployment_id",
            "in": "path",
            "required": true,
            "description": "The deployment's id (`dep_...`). The /v1/deployments routes also take its name.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "default": 20,
              "description": "How many items per page, 1 to 100. Default 20.",
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "description": "Where to go on from: the `next_cursor` of the page before, unchanged. Absent: the first page.",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "object": {
                            "type": "string",
                            "const": "deployment_version",
                            "description": "Always `deployment_version`."
                          },
                          "deployment_id": {
                            "type": "string",
                            "description": "The deployment's id.",
                            "examples": [
                              "dep_8f2k"
                            ]
                          },
                          "version": {
                            "type": "integer",
                            "minimum": -9007199254740991,
                            "maximum": 9007199254740991,
                            "description": "A version number: 1 is the first, and each save adds one."
                          },
                          "manifest": {
                            "type": "object",
                            "properties": {
                              "base": {
                                "default": "bash",
                                "description": "What the deployment is built on: always `bash`.",
                                "type": "string",
                                "const": "bash"
                              },
                              "instructions": {
                                "default": "",
                                "description": "What Bash does here, and how, in plain words, up to 8,000 characters. Empty by default.",
                                "type": "string",
                                "maxLength": 8000
                              },
                              "language": {
                                "default": "auto",
                                "description": "The language Bash speaks: a tag such as `en`, `hi` or `pt-BR`, or `auto` (the default) to follow each user.",
                                "type": "string"
                              },
                              "mcp_servers": {
                                "default": [],
                                "description": "The MCP servers Bash may call, by their `mcp_` ids (POST /v1/mcp-servers).",
                                "type": "array",
                                "items": {
                                  "type": "string"
                                }
                              },
                              "mcp_tool_policy": {
                                "description": "This version's own tool policy for its MCP servers, on top of each server's floor. Absent (every version saved before it): each server's own policy alone.",
                                "maxItems": 50,
                                "type": "array",
                                "items": {
                                  "type": "object",
                                  "properties": {
                                    "server": {
                                      "type": "string",
                                      "description": "The MCP server, by its `mcp_` id, one `mcp_servers` lists."
                                    },
                                    "deny": {
                                      "default": [],
                                      "description": "Tools of the server this version never calls, on top of the server's own floor.",
                                      "maxItems": 200,
                                      "type": "array",
                                      "items": {
                                        "type": "string",
                                        "pattern": "^[A-Za-z0-9_.-]{1,128}$"
                                      }
                                    },
                                    "require_approval": {
                                      "default": [],
                                      "description": "Tools of the server that wait for the person's yes in this version, on top of the server's own floor.",
                                      "maxItems": 200,
                                      "type": "array",
                                      "items": {
                                        "type": "string",
                                        "pattern": "^[A-Za-z0-9_.-]{1,128}$"
                                      }
                                    },
                                    "run_without_asking": {
                                      "description": "Tools of the server this version runs without waiting for the person's yes. Every other tool of the server waits for it, unless the server marks the tool read-only (readOnlyHint).",
                                      "maxItems": 200,
                                      "type": "array",
                                      "items": {
                                        "type": "string",
                                        "pattern": "^[A-Za-z0-9_.-]{1,128}$"
                                      }
                                    }
                                  },
                                  "required": [
                                    "server",
                                    "deny",
                                    "require_approval"
                                  ]
                                }
                              },
                              "apps": {
                                "default": {
                                  "allow": "all"
                                },
                                "description": "Which apps its users may connect.",
                                "type": "object",
                                "properties": {
                                  "allow": {
                                    "default": "all",
                                    "description": "The apps its users may connect: `all` (the default), or a list such as `[\"gmail\"]`.",
                                    "anyOf": [
                                      {
                                        "type": "string",
                                        "const": "all"
                                      },
                                      {
                                        "type": "array",
                                        "items": {
                                          "type": "string"
                                        }
                                      }
                                    ]
                                  }
                                },
                                "required": [
                                  "allow"
                                ]
                              },
                              "approvals": {
                                "default": {
                                  "always": [
                                    "payment",
                                    "booking",
                                    "cancellation"
                                  ]
                                },
                                "description": "What Bash asks the person before doing.",
                                "type": "object",
                                "properties": {
                                  "always": {
                                    "default": [
                                      "payment",
                                      "booking",
                                      "cancellation"
                                    ],
                                    "description": "What Bash asks the person before doing: any of `payment`, `booking`, `cancellation`, `send_email`, `publish` and `delete`. Default the first three. A system approval enforces what `approvals` lists for your own functions and your MCP servers' tools that wait for a yes; in a browser or a connected app, Bash is instructed to ask.",
                                    "type": "array",
                                    "items": {
                                      "type": "string",
                                      "enum": [
                                        "payment",
                                        "booking",
                                        "cancellation",
                                        "send_email",
                                        "publish",
                                        "delete"
                                      ]
                                    }
                                  }
                                },
                                "required": [
                                  "always"
                                ]
                              },
                              "model": {
                                "default": "default",
                                "description": "`default` (the default), or a model id from GET /v1/models.",
                                "type": "string"
                              },
                              "memory": {
                                "default": {},
                                "description": "What Bash remembers about each user here.",
                                "type": "object",
                                "properties": {
                                  "mode": {
                                    "description": "`vestra`, `customer` or `none`. Absent: the company's `memory_mode`.",
                                    "type": "string",
                                    "enum": [
                                      "vestra",
                                      "customer",
                                      "none"
                                    ]
                                  }
                                }
                              },
                              "notebooks": {
                                "default": [],
                                "description": "What Bash reads before it answers: notebooks, by their `nb_` ids.",
                                "type": "array",
                                "items": {
                                  "type": "string"
                                }
                              },
                              "skills": {
                                "default": [],
                                "description": "Skills Bash may use: company skills by their `skl_` ids, or skills Bash already has, by name.",
                                "type": "array",
                                "items": {
                                  "type": "string"
                                }
                              },
                              "tools": {
                                "default": [],
                                "description": "Tools your own code answers: Bash's call reaches you as an interaction of type `tool_call`, after the person's yes unless the tool is marked `read_only` or `run_without_asking`.",
                                "type": "array",
                                "items": {
                                  "type": "object",
                                  "properties": {
                                    "name": {
                                      "type": "string",
                                      "pattern": "^(?!mcp__)[a-z][a-z0-9_]{0,63}$",
                                      "description": "The tool's name: lowercase letters, digits and underscores, starting with a letter, up to 64.",
                                      "examples": [
                                        "get_booking"
                                      ]
                                    },
                                    "description": {
                                      "type": "string",
                                      "minLength": 1,
                                      "maxLength": 1024,
                                      "description": "What the tool does, so Bash knows when to call it, up to 1024 characters.",
                                      "examples": [
                                        "A booking by its PNR"
                                      ]
                                    },
                                    "input_schema": {
                                      "type": "object",
                                      "propertyNames": {
                                        "type": "string"
                                      },
                                      "additionalProperties": {},
                                      "description": "Its arguments, as JSON Schema with `type: object`. Bash's call fills them in.",
                                      "examples": [
                                        {
                                          "type": "object",
                                          "properties": {
                                            "pnr": {
                                              "type": "string"
                                            }
                                          },
                                          "required": [
                                            "pnr"
                                          ]
                                        }
                                      ]
                                    },
                                    "timeout_s": {
                                      "default": 120,
                                      "description": "Seconds Bash waits for your answer, 5 to 600. Default 120; after it, the call expires.",
                                      "type": "integer",
                                      "minimum": 5,
                                      "maximum": 600
                                    },
                                    "read_only": {
                                      "description": "true: the tool changes nothing (a lookup), so Bash calls it without waiting for the person's yes. Absent: false.",
                                      "type": "boolean"
                                    },
                                    "run_without_asking": {
                                      "description": "true: the tool changes something that needs no yes, so Bash calls it without waiting for the person's yes. Absent: false.",
                                      "type": "boolean"
                                    }
                                  },
                                  "required": [
                                    "name",
                                    "description",
                                    "input_schema",
                                    "timeout_s"
                                  ]
                                }
                              },
                              "environment": {
                                "description": "Bash's computer, ready before the first task: a setup script, environment variables, repositories and files. Absent: a plain computer.",
                                "type": "object",
                                "properties": {
                                  "setup_script": {
                                    "description": "A shell script run once on each computer before its first task, and again when the environment changes, up to 20,000 characters. Absent: none.",
                                    "type": "string",
                                    "maxLength": 20000
                                  },
                                  "env": {
                                    "default": {},
                                    "description": "Environment variables on the computer, by name. A credential is `${secret:NAME}`, filled in from your secrets, never a raw value.",
                                    "examples": [
                                      {
                                        "REGION": "ap-south-1"
                                      }
                                    ],
                                    "type": "object",
                                    "propertyNames": {
                                      "type": "string",
                                      "pattern": "^[A-Z_][A-Z0-9_]*$"
                                    },
                                    "additionalProperties": {
                                      "type": "string"
                                    }
                                  },
                                  "repos": {
                                    "default": [],
                                    "description": "Repositories cloned onto the computer.",
                                    "type": "array",
                                    "items": {
                                      "type": "object",
                                      "properties": {
                                        "url": {
                                          "type": "string",
                                          "format": "uri",
                                          "description": "The repository's https URL."
                                        },
                                        "ref": {
                                          "default": "main",
                                          "description": "The branch, tag or commit to check out. Default `main`.",
                                          "type": "string"
                                        },
                                        "path": {
                                          "type": "string",
                                          "description": "The folder on the computer it is cloned into."
                                        },
                                        "token": {
                                          "description": "A token to clone it with, as `${secret:NAME}`. Absent: a public repository.",
                                          "type": "string"
                                        }
                                      },
                                      "required": [
                                        "url",
                                        "ref",
                                        "path"
                                      ]
                                    }
                                  },
                                  "files": {
                                    "default": [],
                                    "description": "Files placed on the computer.",
                                    "type": "array",
                                    "items": {
                                      "type": "object",
                                      "properties": {
                                        "file_id": {
                                          "type": "string",
                                          "description": "A file you uploaded with POST /v1/files, by its `file_` id."
                                        },
                                        "path": {
                                          "type": "string",
                                          "description": "Where it goes on the computer."
                                        }
                                      },
                                      "required": [
                                        "file_id",
                                        "path"
                                      ]
                                    }
                                  }
                                },
                                "required": [
                                  "env",
                                  "repos",
                                  "files"
                                ]
                              },
                              "browser": {
                                "description": "The sites a browser fetch may open, and the pages the browser never opens or acts on. Absent: a fetch opens nothing, and no page is closed.",
                                "type": "object",
                                "properties": {
                                  "allowed_domains": {
                                    "description": "The sites a browser fetch may open, as bare host names such as `ixigo.com`, which also allows `www.ixigo.com`. Up to 20. Absent: a browser fetch opens nothing.",
                                    "examples": [
                                      [
                                        "ixigo.com"
                                      ]
                                    ],
                                    "minItems": 1,
                                    "maxItems": 20,
                                    "type": "array",
                                    "items": {
                                      "type": "string",
                                      "maxLength": 253,
                                      "pattern": "^(?=.{1,253}$)(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\\.)+[a-z][a-z0-9-]{0,61}[a-z0-9]$"
                                    }
                                  },
                                  "blocked_paths": {
                                    "description": "Pages the browser never opens or acts on, as a site and the start of a path, such as `ixigo.com/payments/`. Enforced in code for a browser fetch (403 page_blocked) and Bash's own browser tools. Up to 20.",
                                    "examples": [
                                      [
                                        "ixigo.com/payments/"
                                      ]
                                    ],
                                    "minItems": 1,
                                    "maxItems": 20,
                                    "type": "array",
                                    "items": {
                                      "type": "string",
                                      "maxLength": 300,
                                      "pattern": "^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\\.)+[a-z][a-z0-9-]{0,61}[a-z0-9]\\/[^\\s?#]*$"
                                    }
                                  }
                                }
                              },
                              "routines": {
                                "default": [],
                                "description": "Not used: a version holds no routines. Write them in vestra.yaml, or make them with POST /v1/routines.",
                                "type": "array",
                                "items": {
                                  "type": "object",
                                  "properties": {
                                    "name": {
                                      "type": "string",
                                      "description": "The routine's name."
                                    },
                                    "schedule": {
                                      "type": "string",
                                      "description": "When it runs."
                                    },
                                    "message": {
                                      "type": "string",
                                      "description": "What it asks."
                                    }
                                  },
                                  "required": [
                                    "name",
                                    "schedule",
                                    "message"
                                  ]
                                }
                              },
                              "limits": {
                                "default": {
                                  "spend_per_task_usd": 2
                                },
                                "description": "What one piece of work may spend. There is no time limit.",
                                "type": "object",
                                "properties": {
                                  "spend_per_task_usd": {
                                    "default": 2,
                                    "description": "The most one piece of work may spend, in US dollars, above 0 and at most 100. Default 2.",
                                    "type": "number",
                                    "exclusiveMinimum": 0,
                                    "maximum": 100
                                  }
                                },
                                "required": [
                                  "spend_per_task_usd"
                                ]
                              }
                            },
                            "required": [
                              "base",
                              "instructions",
                              "language",
                              "mcp_servers",
                              "apps",
                              "approvals",
                              "model",
                              "memory",
                              "notebooks",
                              "skills",
                              "tools",
                              "routines",
                              "limits"
                            ],
                            "description": "The version's settings, every default filled in."
                          },
                          "manifest_sha256": {
                            "type": "string",
                            "description": "A hash of the settings: two versions with the same hash run the same."
                          },
                          "skill_pins": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "skill": {
                                  "type": "string",
                                  "description": "The company skill, by its `skl_` id."
                                },
                                "slug": {
                                  "type": "string",
                                  "description": "The skill's name."
                                },
                                "pressing_sha256": {
                                  "anyOf": [
                                    {
                                      "type": "string"
                                    },
                                    {
                                      "type": "null"
                                    }
                                  ],
                                  "description": "The content hash of the skill's version when this version was saved: the one it runs. Null when none was recorded."
                                }
                              },
                              "required": [
                                "skill",
                                "slug",
                                "pressing_sha256"
                              ]
                            },
                            "description": "The company skills this version runs, each at the version of the skill current when it was saved."
                          },
                          "note": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "The note it was saved with; null when none."
                          },
                          "created_by": {
                            "type": "string",
                            "description": "Who saved it: a key's id (`key_...`), `console` (a person in the console), `client` (a session token from your app) or `interview` (the draft the interview wrote)."
                          },
                          "created_at": {
                            "type": "string",
                            "description": "When it was saved, as an ISO 8601 date and time in UTC."
                          },
                          "is_draft": {
                            "type": "boolean",
                            "description": "True when test keys run this version."
                          },
                          "is_live": {
                            "type": "boolean",
                            "description": "True when live keys run it."
                          },
                          "test_verdict": {
                            "description": "Its latest test run's verdict: `passed`, `failed`, or `none` (never tested). Only when you read one version (`GET .../versions/{version}`); absent in the list.",
                            "type": "string",
                            "enum": [
                              "passed",
                              "failed",
                              "none"
                            ]
                          },
                          "interview": {
                            "description": "The interview's closing words, on the version the interview saved; absent on every other version.",
                            "type": "object",
                            "properties": {
                              "summary": {
                                "type": "string",
                                "description": "What the draft sets Bash up to do, in the interview's words."
                              },
                              "tools": {
                                "type": "array",
                                "items": {
                                  "type": "object",
                                  "properties": {
                                    "name": {
                                      "type": "string",
                                      "description": "The tool's name."
                                    },
                                    "description": {
                                      "type": "string",
                                      "description": "What it does."
                                    }
                                  },
                                  "required": [
                                    "name",
                                    "description"
                                  ]
                                },
                                "description": "The tools the file declares that your own code answers."
                              },
                              "per_task_usd": {
                                "type": "number",
                                "description": "The spending cap per piece of work, in US dollars."
                              },
                              "per_task_usd_is_default": {
                                "type": "boolean",
                                "description": "True when that cap is the default, 2, because the file left it."
                              },
                              "tests": {
                                "type": "integer",
                                "minimum": -9007199254740991,
                                "maximum": 9007199254740991,
                                "description": "How many starter tests the file holds."
                              },
                              "next_steps": {
                                "type": "array",
                                "items": {
                                  "type": "string"
                                },
                                "description": "What to do next, one plain line each, in order."
                              }
                            },
                            "required": [
                              "summary",
                              "tools",
                              "per_task_usd",
                              "per_task_usd_is_default",
                              "tests",
                              "next_steps"
                            ]
                          }
                        },
                        "required": [
                          "object",
                          "deployment_id",
                          "version",
                          "manifest",
                          "manifest_sha256",
                          "skill_pins",
                          "note",
                          "created_by",
                          "created_at",
                          "is_draft",
                          "is_live"
                        ]
                      },
                      "description": "The items on this page."
                    },
                    "next_cursor": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Send it as `cursor` for the next page; null on the last page."
                    }
                  },
                  "required": [
                    "data",
                    "next_cursor"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/deployments/{deployment_id}/versions/{version}": {
      "get": {
        "operationId": "getDeploymentsByDeploymentIdVersionsByVersion",
        "summary": "One version, in full.",
        "tags": [
          "Deployments"
        ],
        "x-vestra-line": "deploy",
        "x-vestra-scope": "setup",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "deployment_id",
            "in": "path",
            "required": true,
            "description": "The deployment's id (`dep_...`). The /v1/deployments routes also take its name.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "version",
            "in": "path",
            "required": true,
            "description": "The version number: 1 is the first, and each save adds one.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "type": "string",
                      "const": "deployment_version",
                      "description": "Always `deployment_version`."
                    },
                    "deployment_id": {
                      "type": "string",
                      "description": "The deployment's id.",
                      "examples": [
                        "dep_8f2k"
                      ]
                    },
                    "version": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991,
                      "description": "A version number: 1 is the first, and each save adds one."
                    },
                    "manifest": {
                      "type": "object",
                      "properties": {
                        "base": {
                          "default": "bash",
                          "description": "What the deployment is built on: always `bash`.",
                          "type": "string",
                          "const": "bash"
                        },
                        "instructions": {
                          "default": "",
                          "description": "What Bash does here, and how, in plain words, up to 8,000 characters. Empty by default.",
                          "type": "string",
                          "maxLength": 8000
                        },
                        "language": {
                          "default": "auto",
                          "description": "The language Bash speaks: a tag such as `en`, `hi` or `pt-BR`, or `auto` (the default) to follow each user.",
                          "type": "string"
                        },
                        "mcp_servers": {
                          "default": [],
                          "description": "The MCP servers Bash may call, by their `mcp_` ids (POST /v1/mcp-servers).",
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "mcp_tool_policy": {
                          "description": "This version's own tool policy for its MCP servers, on top of each server's floor. Absent (every version saved before it): each server's own policy alone.",
                          "maxItems": 50,
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "server": {
                                "type": "string",
                                "description": "The MCP server, by its `mcp_` id, one `mcp_servers` lists."
                              },
                              "deny": {
                                "default": [],
                                "description": "Tools of the server this version never calls, on top of the server's own floor.",
                                "maxItems": 200,
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "pattern": "^[A-Za-z0-9_.-]{1,128}$"
                                }
                              },
                              "require_approval": {
                                "default": [],
                                "description": "Tools of the server that wait for the person's yes in this version, on top of the server's own floor.",
                                "maxItems": 200,
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "pattern": "^[A-Za-z0-9_.-]{1,128}$"
                                }
                              },
                              "run_without_asking": {
                                "description": "Tools of the server this version runs without waiting for the person's yes. Every other tool of the server waits for it, unless the server marks the tool read-only (readOnlyHint).",
                                "maxItems": 200,
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "pattern": "^[A-Za-z0-9_.-]{1,128}$"
                                }
                              }
                            },
                            "required": [
                              "server",
                              "deny",
                              "require_approval"
                            ]
                          }
                        },
                        "apps": {
                          "default": {
                            "allow": "all"
                          },
                          "description": "Which apps its users may connect.",
                          "type": "object",
                          "properties": {
                            "allow": {
                              "default": "all",
                              "description": "The apps its users may connect: `all` (the default), or a list such as `[\"gmail\"]`.",
                              "anyOf": [
                                {
                                  "type": "string",
                                  "const": "all"
                                },
                                {
                                  "type": "array",
                                  "items": {
                                    "type": "string"
                                  }
                                }
                              ]
                            }
                          },
                          "required": [
                            "allow"
                          ]
                        },
                        "approvals": {
                          "default": {
                            "always": [
                              "payment",
                              "booking",
                              "cancellation"
                            ]
                          },
                          "description": "What Bash asks the person before doing.",
                          "type": "object",
                          "properties": {
                            "always": {
                              "default": [
                                "payment",
                                "booking",
                                "cancellation"
                              ],
                              "description": "What Bash asks the person before doing: any of `payment`, `booking`, `cancellation`, `send_email`, `publish` and `delete`. Default the first three. A system approval enforces what `approvals` lists for your own functions and your MCP servers' tools that wait for a yes; in a browser or a connected app, Bash is instructed to ask.",
                              "type": "array",
                              "items": {
                                "type": "string",
                                "enum": [
                                  "payment",
                                  "booking",
                                  "cancellation",
                                  "send_email",
                                  "publish",
                                  "delete"
                                ]
                              }
                            }
                          },
                          "required": [
                            "always"
                          ]
                        },
                        "model": {
                          "default": "default",
                          "description": "`default` (the default), or a model id from GET /v1/models.",
                          "type": "string"
                        },
                        "memory": {
                          "default": {},
                          "description": "What Bash remembers about each user here.",
                          "type": "object",
                          "properties": {
                            "mode": {
                              "description": "`vestra`, `customer` or `none`. Absent: the company's `memory_mode`.",
                              "type": "string",
                              "enum": [
                                "vestra",
                                "customer",
                                "none"
                              ]
                            }
                          }
                        },
                        "notebooks": {
                          "default": [],
                          "description": "What Bash reads before it answers: notebooks, by their `nb_` ids.",
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "skills": {
                          "default": [],
                          "description": "Skills Bash may use: company skills by their `skl_` ids, or skills Bash already has, by name.",
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "tools": {
                          "default": [],
                          "description": "Tools your own code answers: Bash's call reaches you as an interaction of type `tool_call`, after the person's yes unless the tool is marked `read_only` or `run_without_asking`.",
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "name": {
                                "type": "string",
                                "pattern": "^(?!mcp__)[a-z][a-z0-9_]{0,63}$",
                                "description": "The tool's name: lowercase letters, digits and underscores, starting with a letter, up to 64.",
                                "examples": [
                                  "get_booking"
                                ]
                              },
                              "description": {
                                "type": "string",
                                "minLength": 1,
                                "maxLength": 1024,
                                "description": "What the tool does, so Bash knows when to call it, up to 1024 characters.",
                                "examples": [
                                  "A booking by its PNR"
                                ]
                              },
                              "input_schema": {
                                "type": "object",
                                "propertyNames": {
                                  "type": "string"
                                },
                                "additionalProperties": {},
                                "description": "Its arguments, as JSON Schema with `type: object`. Bash's call fills them in.",
                                "examples": [
                                  {
                                    "type": "object",
                                    "properties": {
                                      "pnr": {
                                        "type": "string"
                                      }
                                    },
                                    "required": [
                                      "pnr"
                                    ]
                                  }
                                ]
                              },
                              "timeout_s": {
                                "default": 120,
                                "description": "Seconds Bash waits for your answer, 5 to 600. Default 120; after it, the call expires.",
                                "type": "integer",
                                "minimum": 5,
                                "maximum": 600
                              },
                              "read_only": {
                                "description": "true: the tool changes nothing (a lookup), so Bash calls it without waiting for the person's yes. Absent: false.",
                                "type": "boolean"
                              },
                              "run_without_asking": {
                                "description": "true: the tool changes something that needs no yes, so Bash calls it without waiting for the person's yes. Absent: false.",
                                "type": "boolean"
                              }
                            },
                            "required": [
                              "name",
                              "description",
                              "input_schema",
                              "timeout_s"
                            ]
                          }
                        },
                        "environment": {
                          "description": "Bash's computer, ready before the first task: a setup script, environment variables, repositories and files. Absent: a plain computer.",
                          "type": "object",
                          "properties": {
                            "setup_script": {
                              "description": "A shell script run once on each computer before its first task, and again when the environment changes, up to 20,000 characters. Absent: none.",
                              "type": "string",
                              "maxLength": 20000
                            },
                            "env": {
                              "default": {},
                              "description": "Environment variables on the computer, by name. A credential is `${secret:NAME}`, filled in from your secrets, never a raw value.",
                              "examples": [
                                {
                                  "REGION": "ap-south-1"
                                }
                              ],
                              "type": "object",
                              "propertyNames": {
                                "type": "string",
                                "pattern": "^[A-Z_][A-Z0-9_]*$"
                              },
                              "additionalProperties": {
                                "type": "string"
                              }
                            },
                            "repos": {
                              "default": [],
                              "description": "Repositories cloned onto the computer.",
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "url": {
                                    "type": "string",
                                    "format": "uri",
                                    "description": "The repository's https URL."
                                  },
                                  "ref": {
                                    "default": "main",
                                    "description": "The branch, tag or commit to check out. Default `main`.",
                                    "type": "string"
                                  },
                                  "path": {
                                    "type": "string",
                                    "description": "The folder on the computer it is cloned into."
                                  },
                                  "token": {
                                    "description": "A token to clone it with, as `${secret:NAME}`. Absent: a public repository.",
                                    "type": "string"
                                  }
                                },
                                "required": [
                                  "url",
                                  "ref",
                                  "path"
                                ]
                              }
                            },
                            "files": {
                              "default": [],
                              "description": "Files placed on the computer.",
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "file_id": {
                                    "type": "string",
                                    "description": "A file you uploaded with POST /v1/files, by its `file_` id."
                                  },
                                  "path": {
                                    "type": "string",
                                    "description": "Where it goes on the computer."
                                  }
                                },
                                "required": [
                                  "file_id",
                                  "path"
                                ]
                              }
                            }
                          },
                          "required": [
                            "env",
                            "repos",
                            "files"
                          ]
                        },
                        "browser": {
                          "description": "The sites a browser fetch may open, and the pages the browser never opens or acts on. Absent: a fetch opens nothing, and no page is closed.",
                          "type": "object",
                          "properties": {
                            "allowed_domains": {
                              "description": "The sites a browser fetch may open, as bare host names such as `ixigo.com`, which also allows `www.ixigo.com`. Up to 20. Absent: a browser fetch opens nothing.",
                              "examples": [
                                [
                                  "ixigo.com"
                                ]
                              ],
                              "minItems": 1,
                              "maxItems": 20,
                              "type": "array",
                              "items": {
                                "type": "string",
                                "maxLength": 253,
                                "pattern": "^(?=.{1,253}$)(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\\.)+[a-z][a-z0-9-]{0,61}[a-z0-9]$"
                              }
                            },
                            "blocked_paths": {
                              "description": "Pages the browser never opens or acts on, as a site and the start of a path, such as `ixigo.com/payments/`. Enforced in code for a browser fetch (403 page_blocked) and Bash's own browser tools. Up to 20.",
                              "examples": [
                                [
                                  "ixigo.com/payments/"
                                ]
                              ],
                              "minItems": 1,
                              "maxItems": 20,
                              "type": "array",
                              "items": {
                                "type": "string",
                                "maxLength": 300,
                                "pattern": "^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\\.)+[a-z][a-z0-9-]{0,61}[a-z0-9]\\/[^\\s?#]*$"
                              }
                            }
                          }
                        },
                        "routines": {
                          "default": [],
                          "description": "Not used: a version holds no routines. Write them in vestra.yaml, or make them with POST /v1/routines.",
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "name": {
                                "type": "string",
                                "description": "The routine's name."
                              },
                              "schedule": {
                                "type": "string",
                                "description": "When it runs."
                              },
                              "message": {
                                "type": "string",
                                "description": "What it asks."
                              }
                            },
                            "required": [
                              "name",
                              "schedule",
                              "message"
                            ]
                          }
                        },
                        "limits": {
                          "default": {
                            "spend_per_task_usd": 2
                          },
                          "description": "What one piece of work may spend. There is no time limit.",
                          "type": "object",
                          "properties": {
                            "spend_per_task_usd": {
                              "default": 2,
                              "description": "The most one piece of work may spend, in US dollars, above 0 and at most 100. Default 2.",
                              "type": "number",
                              "exclusiveMinimum": 0,
                              "maximum": 100
                            }
                          },
                          "required": [
                            "spend_per_task_usd"
                          ]
                        }
                      },
                      "required": [
                        "base",
                        "instructions",
                        "language",
                        "mcp_servers",
                        "apps",
                        "approvals",
                        "model",
                        "memory",
                        "notebooks",
                        "skills",
                        "tools",
                        "routines",
                        "limits"
                      ],
                      "description": "The version's settings, every default filled in."
                    },
                    "manifest_sha256": {
                      "type": "string",
                      "description": "A hash of the settings: two versions with the same hash run the same."
                    },
                    "skill_pins": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "skill": {
                            "type": "string",
                            "description": "The company skill, by its `skl_` id."
                          },
                          "slug": {
                            "type": "string",
                            "description": "The skill's name."
                          },
                          "pressing_sha256": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "The content hash of the skill's version when this version was saved: the one it runs. Null when none was recorded."
                          }
                        },
                        "required": [
                          "skill",
                          "slug",
                          "pressing_sha256"
                        ]
                      },
                      "description": "The company skills this version runs, each at the version of the skill current when it was saved."
                    },
                    "note": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The note it was saved with; null when none."
                    },
                    "created_by": {
                      "type": "string",
                      "description": "Who saved it: a key's id (`key_...`), `console` (a person in the console), `client` (a session token from your app) or `interview` (the draft the interview wrote)."
                    },
                    "created_at": {
                      "type": "string",
                      "description": "When it was saved, as an ISO 8601 date and time in UTC."
                    },
                    "is_draft": {
                      "type": "boolean",
                      "description": "True when test keys run this version."
                    },
                    "is_live": {
                      "type": "boolean",
                      "description": "True when live keys run it."
                    },
                    "test_verdict": {
                      "description": "Its latest test run's verdict: `passed`, `failed`, or `none` (never tested). Only when you read one version (`GET .../versions/{version}`); absent in the list.",
                      "type": "string",
                      "enum": [
                        "passed",
                        "failed",
                        "none"
                      ]
                    },
                    "interview": {
                      "description": "The interview's closing words, on the version the interview saved; absent on every other version.",
                      "type": "object",
                      "properties": {
                        "summary": {
                          "type": "string",
                          "description": "What the draft sets Bash up to do, in the interview's words."
                        },
                        "tools": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "name": {
                                "type": "string",
                                "description": "The tool's name."
                              },
                              "description": {
                                "type": "string",
                                "description": "What it does."
                              }
                            },
                            "required": [
                              "name",
                              "description"
                            ]
                          },
                          "description": "The tools the file declares that your own code answers."
                        },
                        "per_task_usd": {
                          "type": "number",
                          "description": "The spending cap per piece of work, in US dollars."
                        },
                        "per_task_usd_is_default": {
                          "type": "boolean",
                          "description": "True when that cap is the default, 2, because the file left it."
                        },
                        "tests": {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991,
                          "description": "How many starter tests the file holds."
                        },
                        "next_steps": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "What to do next, one plain line each, in order."
                        }
                      },
                      "required": [
                        "summary",
                        "tools",
                        "per_task_usd",
                        "per_task_usd_is_default",
                        "tests",
                        "next_steps"
                      ]
                    }
                  },
                  "required": [
                    "object",
                    "deployment_id",
                    "version",
                    "manifest",
                    "manifest_sha256",
                    "skill_pins",
                    "note",
                    "created_by",
                    "created_at",
                    "is_draft",
                    "is_live"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/deployments/{deployment_id}/diff": {
      "get": {
        "operationId": "getDeploymentsByDeploymentIdDiff",
        "summary": "What changed between two versions (?from=&to=).",
        "tags": [
          "Deployments"
        ],
        "x-vestra-line": "deploy",
        "x-vestra-scope": "setup",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "deployment_id",
            "in": "path",
            "required": true,
            "description": "The deployment's id (`dep_...`). The /v1/deployments routes also take its name.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "from",
            "in": "query",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 9007199254740991,
              "description": "The version to compare from."
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 9007199254740991,
              "description": "The version to compare to."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "type": "string",
                      "const": "deployment_diff",
                      "description": "Always `deployment_diff`."
                    },
                    "deployment_id": {
                      "type": "string",
                      "description": "The deployment's id.",
                      "examples": [
                        "dep_8f2k"
                      ]
                    },
                    "from": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991,
                      "description": "The version compared from."
                    },
                    "to": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991,
                      "description": "The version compared to."
                    },
                    "changes": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "path": {
                            "type": "string",
                            "description": "The setting that changed, as a path such as `limits.spend_per_task_usd`."
                          },
                          "from": {
                            "description": "Its value in the version compared from; absent when it was not set."
                          },
                          "to": {
                            "description": "Its value in the version compared to; absent when it is not set."
                          }
                        },
                        "required": [
                          "path",
                          "from",
                          "to"
                        ]
                      },
                      "description": "Each setting that differs; empty when the two run the same."
                    }
                  },
                  "required": [
                    "object",
                    "deployment_id",
                    "from",
                    "to",
                    "changes"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/deployments/{deployment_id}/versions/{version}/promote": {
      "post": {
        "operationId": "postDeploymentsByDeploymentIdVersionsByVersionPromote",
        "summary": "Make it live. Refused unless its latest test run passed.",
        "tags": [
          "Deployments"
        ],
        "x-vestra-line": "deploy",
        "x-vestra-scope": "setup",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "deployment_id",
            "in": "path",
            "required": true,
            "description": "The deployment's id (`dep_...`). The /v1/deployments routes also take its name.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "version",
            "in": "path",
            "required": true,
            "description": "The version number: 1 is the first, and each save adds one.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 255
            },
            "description": "Send the same key to retry this call safely for 24 hours."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "deployment": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "The deployment's id.",
                          "examples": [
                            "dep_8f2k"
                          ]
                        },
                        "object": {
                          "type": "string",
                          "const": "deployment",
                          "description": "Always `deployment`."
                        },
                        "name": {
                          "type": "string",
                          "description": "Its name, as people read it."
                        },
                        "slug": {
                          "type": "string",
                          "description": "Its name in URLs and refs: send it where a route takes `{deployment_id}`.",
                          "examples": [
                            "trip-rescue"
                          ]
                        },
                        "description": {
                          "type": "string",
                          "description": "What it is for; empty when none was given."
                        },
                        "base": {
                          "type": "string",
                          "const": "bash",
                          "description": "What it is built on: always `bash`."
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "active",
                            "archived"
                          ],
                          "description": "`active`, or `archived` (put away: no new conversation or version reaches it)."
                        },
                        "draft_version": {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991,
                          "description": "The version test keys run. A new save moves it there; a promote with a test key moves it to the version named, older ones included."
                        },
                        "live_version": {
                          "anyOf": [
                            {
                              "type": "integer",
                              "minimum": -9007199254740991,
                              "maximum": 9007199254740991
                            },
                            {
                              "type": "null"
                            }
                          ],
                          "description": "The version live keys run; null until one is promoted."
                        },
                        "created_at": {
                          "type": "string",
                          "description": "When it was made, as an ISO 8601 date and time in UTC."
                        },
                        "updated_at": {
                          "type": "string",
                          "description": "When it last changed, as an ISO 8601 date and time in UTC."
                        }
                      },
                      "required": [
                        "id",
                        "object",
                        "name",
                        "slug",
                        "description",
                        "base",
                        "status",
                        "draft_version",
                        "live_version",
                        "created_at",
                        "updated_at"
                      ],
                      "description": "The deployment, after the promotion."
                    },
                    "promotion": {
                      "anyOf": [
                        {
                          "type": "object",
                          "properties": {
                            "object": {
                              "type": "string",
                              "const": "deployment_promotion",
                              "description": "Always `deployment_promotion`."
                            },
                            "deployment_id": {
                              "type": "string",
                              "description": "The deployment's id.",
                              "examples": [
                                "dep_8f2k"
                              ]
                            },
                            "action": {
                              "type": "string",
                              "enum": [
                                "promote",
                                "rollback"
                              ],
                              "description": "`promote` (a version went live) or `rollback` (an earlier one went back live)."
                            },
                            "from_version": {
                              "anyOf": [
                                {
                                  "type": "integer",
                                  "minimum": -9007199254740991,
                                  "maximum": 9007199254740991
                                },
                                {
                                  "type": "null"
                                }
                              ],
                              "description": "The version live before; null when none was."
                            },
                            "to_version": {
                              "type": "integer",
                              "minimum": -9007199254740991,
                              "maximum": 9007199254740991,
                              "description": "The version live now."
                            },
                            "verdict": {
                              "type": "string",
                              "enum": [
                                "passed",
                                "failed",
                                "none",
                                "rollback"
                              ],
                              "description": "The version's tests when it went live: `passed`, `none` (there were none to run), or `rollback`."
                            },
                            "created_at": {
                              "type": "string",
                              "description": "When it went live, as an ISO 8601 date and time in UTC."
                            }
                          },
                          "required": [
                            "object",
                            "deployment_id",
                            "action",
                            "from_version",
                            "to_version",
                            "verdict",
                            "created_at"
                          ]
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "What moved; null when the version was already live, so nothing did."
                    },
                    "became_default": {
                      "type": "boolean",
                      "description": "True when this made the deployment the company's default: an ask that names no deployment now reaches it."
                    }
                  },
                  "required": [
                    "deployment",
                    "promotion",
                    "became_default"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/deployments/{deployment_id}/rollback": {
      "post": {
        "operationId": "postDeploymentsByDeploymentIdRollback",
        "summary": "Put an earlier version back live, instantly.",
        "tags": [
          "Deployments"
        ],
        "x-vestra-line": "deploy",
        "x-vestra-scope": "setup",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "deployment_id",
            "in": "path",
            "required": true,
            "description": "The deployment's id (`dep_...`). The /v1/deployments routes also take its name.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 255
            },
            "description": "Send the same key to retry this call safely for 24 hours."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "deployment": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "The deployment's id.",
                          "examples": [
                            "dep_8f2k"
                          ]
                        },
                        "object": {
                          "type": "string",
                          "const": "deployment",
                          "description": "Always `deployment`."
                        },
                        "name": {
                          "type": "string",
                          "description": "Its name, as people read it."
                        },
                        "slug": {
                          "type": "string",
                          "description": "Its name in URLs and refs: send it where a route takes `{deployment_id}`.",
                          "examples": [
                            "trip-rescue"
                          ]
                        },
                        "description": {
                          "type": "string",
                          "description": "What it is for; empty when none was given."
                        },
                        "base": {
                          "type": "string",
                          "const": "bash",
                          "description": "What it is built on: always `bash`."
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "active",
                            "archived"
                          ],
                          "description": "`active`, or `archived` (put away: no new conversation or version reaches it)."
                        },
                        "draft_version": {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991,
                          "description": "The version test keys run. A new save moves it there; a promote with a test key moves it to the version named, older ones included."
                        },
                        "live_version": {
                          "anyOf": [
                            {
                              "type": "integer",
                              "minimum": -9007199254740991,
                              "maximum": 9007199254740991
                            },
                            {
                              "type": "null"
                            }
                          ],
                          "description": "The version live keys run; null until one is promoted."
                        },
                        "created_at": {
                          "type": "string",
                          "description": "When it was made, as an ISO 8601 date and time in UTC."
                        },
                        "updated_at": {
                          "type": "string",
                          "description": "When it last changed, as an ISO 8601 date and time in UTC."
                        }
                      },
                      "required": [
                        "id",
                        "object",
                        "name",
                        "slug",
                        "description",
                        "base",
                        "status",
                        "draft_version",
                        "live_version",
                        "created_at",
                        "updated_at"
                      ],
                      "description": "The deployment, after the promotion."
                    },
                    "promotion": {
                      "anyOf": [
                        {
                          "type": "object",
                          "properties": {
                            "object": {
                              "type": "string",
                              "const": "deployment_promotion",
                              "description": "Always `deployment_promotion`."
                            },
                            "deployment_id": {
                              "type": "string",
                              "description": "The deployment's id.",
                              "examples": [
                                "dep_8f2k"
                              ]
                            },
                            "action": {
                              "type": "string",
                              "enum": [
                                "promote",
                                "rollback"
                              ],
                              "description": "`promote` (a version went live) or `rollback` (an earlier one went back live)."
                            },
                            "from_version": {
                              "anyOf": [
                                {
                                  "type": "integer",
                                  "minimum": -9007199254740991,
                                  "maximum": 9007199254740991
                                },
                                {
                                  "type": "null"
                                }
                              ],
                              "description": "The version live before; null when none was."
                            },
                            "to_version": {
                              "type": "integer",
                              "minimum": -9007199254740991,
                              "maximum": 9007199254740991,
                              "description": "The version live now."
                            },
                            "verdict": {
                              "type": "string",
                              "enum": [
                                "passed",
                                "failed",
                                "none",
                                "rollback"
                              ],
                              "description": "The version's tests when it went live: `passed`, `none` (there were none to run), or `rollback`."
                            },
                            "created_at": {
                              "type": "string",
                              "description": "When it went live, as an ISO 8601 date and time in UTC."
                            }
                          },
                          "required": [
                            "object",
                            "deployment_id",
                            "action",
                            "from_version",
                            "to_version",
                            "verdict",
                            "created_at"
                          ]
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "What moved; null when the version was already live, so nothing did."
                    },
                    "became_default": {
                      "type": "boolean",
                      "description": "True when this made the deployment the company's default: an ask that names no deployment now reaches it."
                    }
                  },
                  "required": [
                    "deployment",
                    "promotion",
                    "became_default"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "version": {
                    "description": "The earlier version to put back live. Absent: the one live before this.",
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 9007199254740991
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/deployments/interview": {
      "post": {
        "operationId": "postDeploymentsInterview",
        "summary": "Build a deployment by talking to Bash: describe the job, answer its questions, receive a draft version.",
        "tags": [
          "Deployments"
        ],
        "x-vestra-line": "init",
        "x-vestra-scope": "setup",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 255
            },
            "description": "Send the same key to retry this call safely for 24 hours."
          }
        ],
        "responses": {
          "202": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "type": "string",
                      "const": "deployment_interview",
                      "description": "Always `deployment_interview`."
                    },
                    "deployment": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "The deployment's id.",
                          "examples": [
                            "dep_8f2k"
                          ]
                        },
                        "object": {
                          "type": "string",
                          "const": "deployment",
                          "description": "Always `deployment`."
                        },
                        "name": {
                          "type": "string",
                          "description": "Its name, as people read it."
                        },
                        "slug": {
                          "type": "string",
                          "description": "Its name in URLs and refs: send it where a route takes `{deployment_id}`.",
                          "examples": [
                            "trip-rescue"
                          ]
                        },
                        "description": {
                          "type": "string",
                          "description": "What it is for; empty when none was given."
                        },
                        "base": {
                          "type": "string",
                          "const": "bash",
                          "description": "What it is built on: always `bash`."
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "active",
                            "archived"
                          ],
                          "description": "`active`, or `archived` (put away: no new conversation or version reaches it)."
                        },
                        "draft_version": {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991,
                          "description": "The version test keys run. A new save moves it there; a promote with a test key moves it to the version named, older ones included."
                        },
                        "live_version": {
                          "anyOf": [
                            {
                              "type": "integer",
                              "minimum": -9007199254740991,
                              "maximum": 9007199254740991
                            },
                            {
                              "type": "null"
                            }
                          ],
                          "description": "The version live keys run; null until one is promoted."
                        },
                        "created_at": {
                          "type": "string",
                          "description": "When it was made, as an ISO 8601 date and time in UTC."
                        },
                        "updated_at": {
                          "type": "string",
                          "description": "When it last changed, as an ISO 8601 date and time in UTC."
                        }
                      },
                      "required": [
                        "id",
                        "object",
                        "name",
                        "slug",
                        "description",
                        "base",
                        "status",
                        "draft_version",
                        "live_version",
                        "created_at",
                        "updated_at"
                      ],
                      "description": "The deployment the interview drafts."
                    },
                    "conversation_id": {
                      "type": "string",
                      "description": "The interview's conversation: follow its events for Bash's questions, and answer with POST /v1/conversations/{conversation_id}/messages."
                    }
                  },
                  "required": [
                    "object",
                    "deployment",
                    "conversation_id"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 120,
                    "description": "The name of the new deployment the interview makes, 1 to 120 characters. It is always new: a taken name gets a numbered slug, and a taken `slug` is refused with 409 `slug_taken`.",
                    "examples": [
                      "Trip rescue"
                    ]
                  },
                  "slug": {
                    "description": "Its name in URLs and refs. Absent: made from `name`.",
                    "examples": [
                      "trip-rescue"
                    ],
                    "type": "string",
                    "pattern": "^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$"
                  },
                  "job": {
                    "type": "string",
                    "minLength": 20,
                    "maxLength": 4000,
                    "description": "What Bash should do for your users, in your own words, 20 to 4,000 characters. Bash asks what it needs, then drafts the file.",
                    "examples": [
                      "Help Tripnest travellers fix broken trips: rebook, refund, find a hotel."
                    ]
                  }
                },
                "required": [
                  "name",
                  "job"
                ]
              }
            }
          }
        }
      }
    },
    "/v1/deployments/{deployment_id}/scenarios": {
      "get": {
        "operationId": "getDeploymentsByDeploymentIdScenarios",
        "summary": "The deployment's test scenarios.",
        "tags": [
          "Tests"
        ],
        "x-vestra-line": "test",
        "x-vestra-scope": "setup",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "deployment_id",
            "in": "path",
            "required": true,
            "description": "The deployment's id (`dep_...`). The /v1/deployments routes also take its name.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "name": {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 120,
                            "description": "Its name, 1 to 120 characters.",
                            "examples": [
                              "Bag allowance"
                            ]
                          },
                          "persona": {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 2000,
                            "description": "Who the test user is, in a few sentences, up to 2,000 characters.",
                            "examples": [
                              "A first-time flyer, anxious, on a phone."
                            ]
                          },
                          "goal": {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 2000,
                            "description": "What the test user wants, in their words, up to 2,000 characters.",
                            "examples": [
                              "How many kilos can I take on booking TN-48213?"
                            ]
                          },
                          "success_criteria": {
                            "minItems": 1,
                            "maxItems": 12,
                            "type": "array",
                            "items": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 500
                            },
                            "description": "What a pass looks like: 1 to 12 lines, each up to 500 characters. Every one must be met.",
                            "examples": [
                              [
                                "Says 7 kg of cabin baggage."
                              ]
                            ]
                          },
                          "must_never": {
                            "default": [],
                            "maxItems": 12,
                            "type": "array",
                            "items": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 500
                            },
                            "description": "What must never happen: up to 12 lines, each up to 500 characters. Any one fails the test.",
                            "examples": [
                              [
                                "Promises a refund."
                              ]
                            ]
                          },
                          "tool_results": {
                            "description": "What each tool answers in this test, as any JSON, at most 20: a declared tool by its name, and a tool of an MCP server as <server>.<tool> (the server's slug), since a test never runs one for real unless the server marks it read-only. A tool with none answers an error.",
                            "examples": [
                              {
                                "get_booking": {
                                  "cabin_kg": 7
                                }
                              }
                            ],
                            "type": "object",
                            "propertyNames": {
                              "type": "string",
                              "pattern": "^(?!mcp__)(?:[a-z][a-z0-9_]{0,63}|[a-z][a-z0-9-]{0,39}\\.[A-Za-z0-9_.-]{1,128})$"
                            },
                            "additionalProperties": {}
                          },
                          "approves": {
                            "description": "true: the test user says yes to each approval for a tool of one of the deployment's own MCP servers, which in a test plays its tool_results entry or does not run. Absent or false: it says no to every approval. Anything else that waits for a yes is always declined.",
                            "examples": [
                              true
                            ],
                            "type": "boolean"
                          },
                          "id": {
                            "type": "string",
                            "description": "The scenario's id."
                          },
                          "object": {
                            "type": "string",
                            "const": "scenario",
                            "description": "Always `scenario`."
                          },
                          "deployment_id": {
                            "type": "string",
                            "description": "The deployment it tests."
                          },
                          "created_at": {
                            "type": "string",
                            "description": "When it was made, as an ISO 8601 date and time in UTC."
                          },
                          "updated_at": {
                            "type": "string",
                            "description": "When it last changed, as an ISO 8601 date and time in UTC."
                          }
                        },
                        "required": [
                          "name",
                          "persona",
                          "goal",
                          "success_criteria",
                          "must_never",
                          "id",
                          "object",
                          "deployment_id",
                          "created_at",
                          "updated_at"
                        ]
                      },
                      "description": "The items on this page."
                    },
                    "next_cursor": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Send it as `cursor` for the next page; null on the last page."
                    }
                  },
                  "required": [
                    "data",
                    "next_cursor"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "postDeploymentsByDeploymentIdScenarios",
        "summary": "Add one: a pretend user, their goal, what success looks like, what must never happen.",
        "tags": [
          "Tests"
        ],
        "x-vestra-line": "test",
        "x-vestra-scope": "setup",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "deployment_id",
            "in": "path",
            "required": true,
            "description": "The deployment's id (`dep_...`). The /v1/deployments routes also take its name.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 255
            },
            "description": "Send the same key to retry this call safely for 24 hours."
          }
        ],
        "responses": {
          "201": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "name": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 120,
                      "description": "Its name, 1 to 120 characters.",
                      "examples": [
                        "Bag allowance"
                      ]
                    },
                    "persona": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 2000,
                      "description": "Who the test user is, in a few sentences, up to 2,000 characters.",
                      "examples": [
                        "A first-time flyer, anxious, on a phone."
                      ]
                    },
                    "goal": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 2000,
                      "description": "What the test user wants, in their words, up to 2,000 characters.",
                      "examples": [
                        "How many kilos can I take on booking TN-48213?"
                      ]
                    },
                    "success_criteria": {
                      "minItems": 1,
                      "maxItems": 12,
                      "type": "array",
                      "items": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 500
                      },
                      "description": "What a pass looks like: 1 to 12 lines, each up to 500 characters. Every one must be met.",
                      "examples": [
                        [
                          "Says 7 kg of cabin baggage."
                        ]
                      ]
                    },
                    "must_never": {
                      "default": [],
                      "maxItems": 12,
                      "type": "array",
                      "items": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 500
                      },
                      "description": "What must never happen: up to 12 lines, each up to 500 characters. Any one fails the test.",
                      "examples": [
                        [
                          "Promises a refund."
                        ]
                      ]
                    },
                    "tool_results": {
                      "description": "What each tool answers in this test, as any JSON, at most 20: a declared tool by its name, and a tool of an MCP server as <server>.<tool> (the server's slug), since a test never runs one for real unless the server marks it read-only. A tool with none answers an error.",
                      "examples": [
                        {
                          "get_booking": {
                            "cabin_kg": 7
                          }
                        }
                      ],
                      "type": "object",
                      "propertyNames": {
                        "type": "string",
                        "pattern": "^(?!mcp__)(?:[a-z][a-z0-9_]{0,63}|[a-z][a-z0-9-]{0,39}\\.[A-Za-z0-9_.-]{1,128})$"
                      },
                      "additionalProperties": {}
                    },
                    "approves": {
                      "description": "true: the test user says yes to each approval for a tool of one of the deployment's own MCP servers, which in a test plays its tool_results entry or does not run. Absent or false: it says no to every approval. Anything else that waits for a yes is always declined.",
                      "examples": [
                        true
                      ],
                      "type": "boolean"
                    },
                    "id": {
                      "type": "string",
                      "description": "The scenario's id."
                    },
                    "object": {
                      "type": "string",
                      "const": "scenario",
                      "description": "Always `scenario`."
                    },
                    "deployment_id": {
                      "type": "string",
                      "description": "The deployment it tests."
                    },
                    "created_at": {
                      "type": "string",
                      "description": "When it was made, as an ISO 8601 date and time in UTC."
                    },
                    "updated_at": {
                      "type": "string",
                      "description": "When it last changed, as an ISO 8601 date and time in UTC."
                    }
                  },
                  "required": [
                    "name",
                    "persona",
                    "goal",
                    "success_criteria",
                    "must_never",
                    "id",
                    "object",
                    "deployment_id",
                    "created_at",
                    "updated_at"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 120,
                    "description": "Its name, 1 to 120 characters.",
                    "examples": [
                      "Bag allowance"
                    ]
                  },
                  "persona": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 2000,
                    "description": "Who the test user is, in a few sentences, up to 2,000 characters.",
                    "examples": [
                      "A first-time flyer, anxious, on a phone."
                    ]
                  },
                  "goal": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 2000,
                    "description": "What the test user wants, in their words, up to 2,000 characters.",
                    "examples": [
                      "How many kilos can I take on booking TN-48213?"
                    ]
                  },
                  "success_criteria": {
                    "minItems": 1,
                    "maxItems": 12,
                    "type": "array",
                    "items": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 500
                    },
                    "description": "What a pass looks like: 1 to 12 lines, each up to 500 characters. Every one must be met.",
                    "examples": [
                      [
                        "Says 7 kg of cabin baggage."
                      ]
                    ]
                  },
                  "must_never": {
                    "default": [],
                    "maxItems": 12,
                    "type": "array",
                    "items": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 500
                    },
                    "description": "What must never happen: up to 12 lines, each up to 500 characters. Any one fails the test.",
                    "examples": [
                      [
                        "Promises a refund."
                      ]
                    ]
                  },
                  "tool_results": {
                    "description": "What each tool answers in this test, as any JSON, at most 20: a declared tool by its name, and a tool of an MCP server as <server>.<tool> (the server's slug), since a test never runs one for real unless the server marks it read-only. A tool with none answers an error.",
                    "examples": [
                      {
                        "get_booking": {
                          "cabin_kg": 7
                        }
                      }
                    ],
                    "type": "object",
                    "propertyNames": {
                      "type": "string",
                      "pattern": "^(?!mcp__)(?:[a-z][a-z0-9_]{0,63}|[a-z][a-z0-9-]{0,39}\\.[A-Za-z0-9_.-]{1,128})$"
                    },
                    "additionalProperties": {}
                  },
                  "approves": {
                    "description": "true: the test user says yes to each approval for a tool of one of the deployment's own MCP servers, which in a test plays its tool_results entry or does not run. Absent or false: it says no to every approval. Anything else that waits for a yes is always declined.",
                    "examples": [
                      true
                    ],
                    "type": "boolean"
                  }
                },
                "required": [
                  "name",
                  "persona",
                  "goal",
                  "success_criteria"
                ]
              }
            }
          }
        }
      }
    },
    "/v1/deployments/{deployment_id}/scenarios/generate": {
      "post": {
        "operationId": "postDeploymentsByDeploymentIdScenariosGenerate",
        "summary": "Have Bash draft scenarios from the deployment's instructions.",
        "tags": [
          "Tests"
        ],
        "x-vestra-line": "test",
        "x-vestra-scope": "setup",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "deployment_id",
            "in": "path",
            "required": true,
            "description": "The deployment's id (`dep_...`). The /v1/deployments routes also take its name.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 255
            },
            "description": "Send the same key to retry this call safely for 24 hours."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "type": "string",
                      "const": "list",
                      "description": "Always `list`."
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "name": {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 120,
                            "description": "Its name, 1 to 120 characters.",
                            "examples": [
                              "Bag allowance"
                            ]
                          },
                          "persona": {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 2000,
                            "description": "Who the test user is, in a few sentences, up to 2,000 characters.",
                            "examples": [
                              "A first-time flyer, anxious, on a phone."
                            ]
                          },
                          "goal": {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 2000,
                            "description": "What the test user wants, in their words, up to 2,000 characters.",
                            "examples": [
                              "How many kilos can I take on booking TN-48213?"
                            ]
                          },
                          "success_criteria": {
                            "minItems": 1,
                            "maxItems": 12,
                            "type": "array",
                            "items": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 500
                            },
                            "description": "What a pass looks like: 1 to 12 lines, each up to 500 characters. Every one must be met.",
                            "examples": [
                              [
                                "Says 7 kg of cabin baggage."
                              ]
                            ]
                          },
                          "must_never": {
                            "default": [],
                            "maxItems": 12,
                            "type": "array",
                            "items": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 500
                            },
                            "description": "What must never happen: up to 12 lines, each up to 500 characters. Any one fails the test.",
                            "examples": [
                              [
                                "Promises a refund."
                              ]
                            ]
                          },
                          "tool_results": {
                            "description": "What each tool answers in this test, as any JSON, at most 20: a declared tool by its name, and a tool of an MCP server as <server>.<tool> (the server's slug), since a test never runs one for real unless the server marks it read-only. A tool with none answers an error.",
                            "examples": [
                              {
                                "get_booking": {
                                  "cabin_kg": 7
                                }
                              }
                            ],
                            "type": "object",
                            "propertyNames": {
                              "type": "string",
                              "pattern": "^(?!mcp__)(?:[a-z][a-z0-9_]{0,63}|[a-z][a-z0-9-]{0,39}\\.[A-Za-z0-9_.-]{1,128})$"
                            },
                            "additionalProperties": {}
                          },
                          "approves": {
                            "description": "true: the test user says yes to each approval for a tool of one of the deployment's own MCP servers, which in a test plays its tool_results entry or does not run. Absent or false: it says no to every approval. Anything else that waits for a yes is always declined.",
                            "examples": [
                              true
                            ],
                            "type": "boolean"
                          }
                        },
                        "required": [
                          "name",
                          "persona",
                          "goal",
                          "success_criteria",
                          "must_never"
                        ]
                      },
                      "description": "The drafted tests. They are not saved: save the ones you want, or write them into vestra.yaml."
                    }
                  },
                  "required": [
                    "object",
                    "data"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "count": {
                    "default": 5,
                    "description": "How many tests to draft, 1 to 10. Default 5.",
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 10
                  },
                  "version": {
                    "description": "The version whose instructions they are drafted from. Absent: the newest.",
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 9007199254740991
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/deployments/{deployment_id}/scenarios/{scenario_id}": {
      "patch": {
        "operationId": "patchDeploymentsByDeploymentIdScenariosByScenarioId",
        "summary": "Change one.",
        "tags": [
          "Tests"
        ],
        "x-vestra-line": "test",
        "x-vestra-scope": "setup",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "deployment_id",
            "in": "path",
            "required": true,
            "description": "The deployment's id (`dep_...`). The /v1/deployments routes also take its name.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "scenario_id",
            "in": "path",
            "required": true,
            "description": "The test scenario's id (`scn_...`).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "name": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 120,
                      "description": "Its name, 1 to 120 characters.",
                      "examples": [
                        "Bag allowance"
                      ]
                    },
                    "persona": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 2000,
                      "description": "Who the test user is, in a few sentences, up to 2,000 characters.",
                      "examples": [
                        "A first-time flyer, anxious, on a phone."
                      ]
                    },
                    "goal": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 2000,
                      "description": "What the test user wants, in their words, up to 2,000 characters.",
                      "examples": [
                        "How many kilos can I take on booking TN-48213?"
                      ]
                    },
                    "success_criteria": {
                      "minItems": 1,
                      "maxItems": 12,
                      "type": "array",
                      "items": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 500
                      },
                      "description": "What a pass looks like: 1 to 12 lines, each up to 500 characters. Every one must be met.",
                      "examples": [
                        [
                          "Says 7 kg of cabin baggage."
                        ]
                      ]
                    },
                    "must_never": {
                      "default": [],
                      "maxItems": 12,
                      "type": "array",
                      "items": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 500
                      },
                      "description": "What must never happen: up to 12 lines, each up to 500 characters. Any one fails the test.",
                      "examples": [
                        [
                          "Promises a refund."
                        ]
                      ]
                    },
                    "tool_results": {
                      "description": "What each tool answers in this test, as any JSON, at most 20: a declared tool by its name, and a tool of an MCP server as <server>.<tool> (the server's slug), since a test never runs one for real unless the server marks it read-only. A tool with none answers an error.",
                      "examples": [
                        {
                          "get_booking": {
                            "cabin_kg": 7
                          }
                        }
                      ],
                      "type": "object",
                      "propertyNames": {
                        "type": "string",
                        "pattern": "^(?!mcp__)(?:[a-z][a-z0-9_]{0,63}|[a-z][a-z0-9-]{0,39}\\.[A-Za-z0-9_.-]{1,128})$"
                      },
                      "additionalProperties": {}
                    },
                    "approves": {
                      "description": "true: the test user says yes to each approval for a tool of one of the deployment's own MCP servers, which in a test plays its tool_results entry or does not run. Absent or false: it says no to every approval. Anything else that waits for a yes is always declined.",
                      "examples": [
                        true
                      ],
                      "type": "boolean"
                    },
                    "id": {
                      "type": "string",
                      "description": "The scenario's id."
                    },
                    "object": {
                      "type": "string",
                      "const": "scenario",
                      "description": "Always `scenario`."
                    },
                    "deployment_id": {
                      "type": "string",
                      "description": "The deployment it tests."
                    },
                    "created_at": {
                      "type": "string",
                      "description": "When it was made, as an ISO 8601 date and time in UTC."
                    },
                    "updated_at": {
                      "type": "string",
                      "description": "When it last changed, as an ISO 8601 date and time in UTC."
                    }
                  },
                  "required": [
                    "name",
                    "persona",
                    "goal",
                    "success_criteria",
                    "must_never",
                    "id",
                    "object",
                    "deployment_id",
                    "created_at",
                    "updated_at"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 120,
                    "description": "Its name, 1 to 120 characters.",
                    "examples": [
                      "Bag allowance"
                    ]
                  },
                  "persona": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 2000,
                    "description": "Who the test user is, in a few sentences, up to 2,000 characters.",
                    "examples": [
                      "A first-time flyer, anxious, on a phone."
                    ]
                  },
                  "goal": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 2000,
                    "description": "What the test user wants, in their words, up to 2,000 characters.",
                    "examples": [
                      "How many kilos can I take on booking TN-48213?"
                    ]
                  },
                  "success_criteria": {
                    "minItems": 1,
                    "maxItems": 12,
                    "type": "array",
                    "items": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 500
                    },
                    "description": "What a pass looks like: 1 to 12 lines, each up to 500 characters. Every one must be met.",
                    "examples": [
                      [
                        "Says 7 kg of cabin baggage."
                      ]
                    ]
                  },
                  "must_never": {
                    "maxItems": 12,
                    "type": "array",
                    "items": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 500
                    },
                    "description": "What must never happen: up to 12 lines, each up to 500 characters. Any one fails the test.",
                    "examples": [
                      [
                        "Promises a refund."
                      ]
                    ]
                  },
                  "tool_results": {
                    "description": "What each tool answers in this test, as any JSON, at most 20: a declared tool by its name, and a tool of an MCP server as <server>.<tool> (the server's slug), since a test never runs one for real unless the server marks it read-only. A tool with none answers an error.",
                    "examples": [
                      {
                        "get_booking": {
                          "cabin_kg": 7
                        }
                      }
                    ],
                    "type": "object",
                    "propertyNames": {
                      "type": "string",
                      "pattern": "^(?!mcp__)(?:[a-z][a-z0-9_]{0,63}|[a-z][a-z0-9-]{0,39}\\.[A-Za-z0-9_.-]{1,128})$"
                    },
                    "additionalProperties": {}
                  },
                  "approves": {
                    "description": "true: the test user says yes to each approval for a tool of one of the deployment's own MCP servers, which in a test plays its tool_results entry or does not run. Absent or false: it says no to every approval. Anything else that waits for a yes is always declined.",
                    "examples": [
                      true
                    ],
                    "type": "boolean"
                  }
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteDeploymentsByDeploymentIdScenariosByScenarioId",
        "summary": "Remove one.",
        "tags": [
          "Tests"
        ],
        "x-vestra-line": "test",
        "x-vestra-scope": "setup",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "deployment_id",
            "in": "path",
            "required": true,
            "description": "The deployment's id (`dep_...`). The /v1/deployments routes also take its name.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "scenario_id",
            "in": "path",
            "required": true,
            "description": "The test scenario's id (`scn_...`).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "The deleted scenario's id."
                    },
                    "object": {
                      "type": "string",
                      "const": "scenario",
                      "description": "Always `scenario`."
                    },
                    "deleted": {
                      "type": "boolean",
                      "const": true,
                      "description": "Always true: no test run plays it again."
                    }
                  },
                  "required": [
                    "id",
                    "object",
                    "deleted"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/deployments/{deployment_id}/test-runs": {
      "post": {
        "operationId": "postDeploymentsByDeploymentIdTestRuns",
        "summary": "Run every scenario against a version: version, or the latest when left out. The deployment is named by its id or its name. user_secrets sets the test user's own secrets for your MCP servers, replacing any an earlier run set.",
        "tags": [
          "Tests"
        ],
        "x-vestra-line": "test",
        "x-vestra-scope": "setup",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "deployment_id",
            "in": "path",
            "required": true,
            "description": "The deployment's id (`dep_...`). The /v1/deployments routes also take its name.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 255
            },
            "description": "Send the same key to retry this call safely for 24 hours."
          }
        ],
        "responses": {
          "202": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "The test run's id.",
                      "examples": [
                        "trun_8f2k"
                      ]
                    },
                    "object": {
                      "type": "string",
                      "const": "test_run",
                      "description": "Always `test_run`."
                    },
                    "deployment_id": {
                      "type": "string",
                      "description": "The deployment it tests."
                    },
                    "version": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991,
                      "description": "The version it tests."
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "queued",
                        "running",
                        "passed",
                        "failed",
                        "error"
                      ],
                      "description": "`queued` or `running` while it plays. `passed`: every scenario passed. `failed`: one or more did not. `error`: it could not finish, as `error_code` says."
                    },
                    "error_code": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Why it ended in `error`: `interrupted` (a restart stopped it too often), `test_wallet_empty`, `judge_unreadable` (the grader's answer could not be read) or `internal`. Null otherwise."
                    },
                    "scenario_count": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991,
                      "description": "How many scenarios it plays."
                    },
                    "passed_count": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991,
                      "description": "How many have passed so far."
                    },
                    "resumes": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991,
                      "description": "How many times a restart interrupted it and it played on from where it was, at most 2."
                    },
                    "promoted": {
                      "anyOf": [
                        {
                          "type": "object",
                          "properties": {
                            "mode": {
                              "type": "string",
                              "enum": [
                                "live",
                                "test"
                              ],
                              "description": "The mode the version went live in."
                            },
                            "version": {
                              "type": "integer",
                              "minimum": -9007199254740991,
                              "maximum": 9007199254740991,
                              "description": "The version that went live."
                            }
                          },
                          "required": [
                            "mode",
                            "version"
                          ]
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "What its pass promoted, for an apply that promotes after its tests; null when it promoted nothing (none asked, refused, or it did not pass)."
                    },
                    "became_default": {
                      "type": "boolean",
                      "description": "True when that promotion made the deployment the company's default: an ask with no deployment now reaches it."
                    },
                    "cost_usd": {
                      "type": "number",
                      "description": "What the run cost, in billed US dollars."
                    },
                    "created_at": {
                      "type": "string",
                      "description": "When it was asked for, as an ISO 8601 date and time in UTC."
                    },
                    "started_at": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "When it began to play; null while queued."
                    },
                    "finished_at": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "When it ended; null while it plays."
                    },
                    "results": {
                      "description": "Each scenario's result, on GET /v1/test-runs/{test_run_id}; absent in lists.",
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "object": {
                            "type": "string",
                            "const": "test_result",
                            "description": "Always `test_result`."
                          },
                          "scenario_id": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "The scenario it played; null when the scenario was deleted since."
                          },
                          "scenario": {
                            "type": "object",
                            "properties": {
                              "name": {
                                "type": "string",
                                "minLength": 1,
                                "maxLength": 120,
                                "description": "Its name, 1 to 120 characters.",
                                "examples": [
                                  "Bag allowance"
                                ]
                              },
                              "persona": {
                                "type": "string",
                                "minLength": 1,
                                "maxLength": 2000,
                                "description": "Who the test user is, in a few sentences, up to 2,000 characters.",
                                "examples": [
                                  "A first-time flyer, anxious, on a phone."
                                ]
                              },
                              "goal": {
                                "type": "string",
                                "minLength": 1,
                                "maxLength": 2000,
                                "description": "What the test user wants, in their words, up to 2,000 characters.",
                                "examples": [
                                  "How many kilos can I take on booking TN-48213?"
                                ]
                              },
                              "success_criteria": {
                                "minItems": 1,
                                "maxItems": 12,
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 500
                                },
                                "description": "What a pass looks like: 1 to 12 lines, each up to 500 characters. Every one must be met.",
                                "examples": [
                                  [
                                    "Says 7 kg of cabin baggage."
                                  ]
                                ]
                              },
                              "must_never": {
                                "default": [],
                                "maxItems": 12,
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 500
                                },
                                "description": "What must never happen: up to 12 lines, each up to 500 characters. Any one fails the test.",
                                "examples": [
                                  [
                                    "Promises a refund."
                                  ]
                                ]
                              },
                              "tool_results": {
                                "description": "What each tool answers in this test, as any JSON, at most 20: a declared tool by its name, and a tool of an MCP server as <server>.<tool> (the server's slug), since a test never runs one for real unless the server marks it read-only. A tool with none answers an error.",
                                "examples": [
                                  {
                                    "get_booking": {
                                      "cabin_kg": 7
                                    }
                                  }
                                ],
                                "type": "object",
                                "propertyNames": {
                                  "type": "string",
                                  "pattern": "^(?!mcp__)(?:[a-z][a-z0-9_]{0,63}|[a-z][a-z0-9-]{0,39}\\.[A-Za-z0-9_.-]{1,128})$"
                                },
                                "additionalProperties": {}
                              },
                              "approves": {
                                "description": "true: the test user says yes to each approval for a tool of one of the deployment's own MCP servers, which in a test plays its tool_results entry or does not run. Absent or false: it says no to every approval. Anything else that waits for a yes is always declined.",
                                "examples": [
                                  true
                                ],
                                "type": "boolean"
                              }
                            },
                            "required": [
                              "name",
                              "persona",
                              "goal",
                              "success_criteria",
                              "must_never"
                            ],
                            "description": "The scenario as it was played."
                          },
                          "verdict": {
                            "type": "string",
                            "enum": [
                              "passed",
                              "failed",
                              "error"
                            ],
                            "description": "`passed`: every line of success met and nothing it must never do. `failed`: not so. `error`: it could not be played to the end."
                          },
                          "reason": {
                            "type": "string",
                            "description": "Why, in a sentence or two."
                          },
                          "criteria": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "criterion": {
                                  "type": "string",
                                  "description": "One line of what a pass looks like."
                                },
                                "met": {
                                  "type": "boolean",
                                  "description": "Whether the conversation met it."
                                },
                                "evidence": {
                                  "type": "string",
                                  "description": "Why the grader says so, from the conversation."
                                }
                              },
                              "required": [
                                "criterion",
                                "met",
                                "evidence"
                              ]
                            },
                            "description": "Each line of success, graded."
                          },
                          "must_never": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "rule": {
                                  "type": "string",
                                  "description": "One line of what must never happen."
                                },
                                "violated": {
                                  "type": "boolean",
                                  "description": "Whether it happened."
                                },
                                "evidence": {
                                  "type": "string",
                                  "description": "Why the grader says so, from the conversation."
                                }
                              },
                              "required": [
                                "rule",
                                "violated",
                                "evidence"
                              ]
                            },
                            "description": "Each thing it must never do, graded."
                          },
                          "approvals_asked": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "kind": {
                                  "type": "string",
                                  "description": "The kind of ask Bash raised, such as `hands_approval`, `credit_approval` or `tool_permission`."
                                },
                                "category": {
                                  "type": "string",
                                  "enum": [
                                    "payment",
                                    "account_action",
                                    "connect_app",
                                    "action",
                                    "custom"
                                  ],
                                  "description": "What it would have done: a `payment`, an `account_action`, `connect_app`, another `action`, or `custom`."
                                },
                                "summary": {
                                  "type": "string",
                                  "description": "What it asked to do, in its words."
                                },
                                "decision": {
                                  "type": "string",
                                  "enum": [
                                    "denied",
                                    "approved"
                                  ],
                                  "description": "What the test user said. It denies anything that would act for it, so a test never moves money or changes an account; a test with approves: true approves the tools of the deployment's own MCP servers, which a test plays from its tool_results or does not run."
                                }
                              },
                              "required": [
                                "kind",
                                "category",
                                "summary",
                                "decision"
                              ]
                            },
                            "description": "What Bash asked the test user's yes for, and what it said."
                          },
                          "transcript": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "role": {
                                  "type": "string",
                                  "enum": [
                                    "customer",
                                    "bash",
                                    "note"
                                  ],
                                  "description": "Who said it: `customer` (the test user), `bash`, or a `note` on what happened (work started, a tool called)."
                                },
                                "text": {
                                  "type": "string",
                                  "description": "What was said, or what happened."
                                }
                              },
                              "required": [
                                "role",
                                "text"
                              ]
                            },
                            "description": "The conversation, line by line."
                          },
                          "conversation_id": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "The test conversation; null when it never started."
                          },
                          "cost_usd": {
                            "type": "number",
                            "description": "What playing it cost, in billed US dollars."
                          }
                        },
                        "required": [
                          "object",
                          "scenario_id",
                          "scenario",
                          "verdict",
                          "reason",
                          "criteria",
                          "must_never",
                          "approvals_asked",
                          "transcript",
                          "conversation_id",
                          "cost_usd"
                        ]
                      }
                    }
                  },
                  "required": [
                    "id",
                    "object",
                    "deployment_id",
                    "version",
                    "status",
                    "error_code",
                    "scenario_count",
                    "passed_count",
                    "resumes",
                    "promoted",
                    "became_default",
                    "cost_usd",
                    "created_at",
                    "started_at",
                    "finished_at"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "version": {
                    "description": "The version to test. Absent: the newest.",
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 9007199254740991
                  },
                  "user_secrets": {
                    "description": "The test user's own secrets, by name, at most 20, for headers such as `${user_secret:NAME}`. They replace the whole set: `{}` clears it, and a run that sends none keeps the last. Never returned.",
                    "examples": [
                      {
                        "AGENCY_ID": "..."
                      }
                    ],
                    "type": "object",
                    "propertyNames": {
                      "type": "string",
                      "pattern": "^[A-Z0-9_]{1,64}$",
                      "description": "A user secret's name: 1 to 64 of A-Z, 0-9 and _.",
                      "examples": [
                        "GMAIL_TOKEN"
                      ]
                    },
                    "additionalProperties": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 8192,
                      "description": "The secret, in at most 8,192 characters. It is never shown again, not even to you."
                    }
                  }
                },
                "additionalProperties": false
              }
            }
          }
        }
      },
      "get": {
        "operationId": "getDeploymentsByDeploymentIdTestRuns",
        "summary": "Past test runs.",
        "tags": [
          "Tests"
        ],
        "x-vestra-line": "test",
        "x-vestra-scope": "setup",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "deployment_id",
            "in": "path",
            "required": true,
            "description": "The deployment's id (`dep_...`). The /v1/deployments routes also take its name.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "default": 20,
              "description": "How many items per page, 1 to 100. Default 20.",
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "description": "Where to go on from: the `next_cursor` of the page before, unchanged. Absent: the first page.",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "The test run's id.",
                            "examples": [
                              "trun_8f2k"
                            ]
                          },
                          "object": {
                            "type": "string",
                            "const": "test_run",
                            "description": "Always `test_run`."
                          },
                          "deployment_id": {
                            "type": "string",
                            "description": "The deployment it tests."
                          },
                          "version": {
                            "type": "integer",
                            "minimum": -9007199254740991,
                            "maximum": 9007199254740991,
                            "description": "The version it tests."
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "queued",
                              "running",
                              "passed",
                              "failed",
                              "error"
                            ],
                            "description": "`queued` or `running` while it plays. `passed`: every scenario passed. `failed`: one or more did not. `error`: it could not finish, as `error_code` says."
                          },
                          "error_code": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "Why it ended in `error`: `interrupted` (a restart stopped it too often), `test_wallet_empty`, `judge_unreadable` (the grader's answer could not be read) or `internal`. Null otherwise."
                          },
                          "scenario_count": {
                            "type": "integer",
                            "minimum": -9007199254740991,
                            "maximum": 9007199254740991,
                            "description": "How many scenarios it plays."
                          },
                          "passed_count": {
                            "type": "integer",
                            "minimum": -9007199254740991,
                            "maximum": 9007199254740991,
                            "description": "How many have passed so far."
                          },
                          "resumes": {
                            "type": "integer",
                            "minimum": -9007199254740991,
                            "maximum": 9007199254740991,
                            "description": "How many times a restart interrupted it and it played on from where it was, at most 2."
                          },
                          "promoted": {
                            "anyOf": [
                              {
                                "type": "object",
                                "properties": {
                                  "mode": {
                                    "type": "string",
                                    "enum": [
                                      "live",
                                      "test"
                                    ],
                                    "description": "The mode the version went live in."
                                  },
                                  "version": {
                                    "type": "integer",
                                    "minimum": -9007199254740991,
                                    "maximum": 9007199254740991,
                                    "description": "The version that went live."
                                  }
                                },
                                "required": [
                                  "mode",
                                  "version"
                                ]
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "What its pass promoted, for an apply that promotes after its tests; null when it promoted nothing (none asked, refused, or it did not pass)."
                          },
                          "became_default": {
                            "type": "boolean",
                            "description": "True when that promotion made the deployment the company's default: an ask with no deployment now reaches it."
                          },
                          "cost_usd": {
                            "type": "number",
                            "description": "What the run cost, in billed US dollars."
                          },
                          "created_at": {
                            "type": "string",
                            "description": "When it was asked for, as an ISO 8601 date and time in UTC."
                          },
                          "started_at": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "When it began to play; null while queued."
                          },
                          "finished_at": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "When it ended; null while it plays."
                          },
                          "results": {
                            "description": "Each scenario's result, on GET /v1/test-runs/{test_run_id}; absent in lists.",
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "object": {
                                  "type": "string",
                                  "const": "test_result",
                                  "description": "Always `test_result`."
                                },
                                "scenario_id": {
                                  "anyOf": [
                                    {
                                      "type": "string"
                                    },
                                    {
                                      "type": "null"
                                    }
                                  ],
                                  "description": "The scenario it played; null when the scenario was deleted since."
                                },
                                "scenario": {
                                  "type": "object",
                                  "properties": {
                                    "name": {
                                      "type": "string",
                                      "minLength": 1,
                                      "maxLength": 120,
                                      "description": "Its name, 1 to 120 characters.",
                                      "examples": [
                                        "Bag allowance"
                                      ]
                                    },
                                    "persona": {
                                      "type": "string",
                                      "minLength": 1,
                                      "maxLength": 2000,
                                      "description": "Who the test user is, in a few sentences, up to 2,000 characters.",
                                      "examples": [
                                        "A first-time flyer, anxious, on a phone."
                                      ]
                                    },
                                    "goal": {
                                      "type": "string",
                                      "minLength": 1,
                                      "maxLength": 2000,
                                      "description": "What the test user wants, in their words, up to 2,000 characters.",
                                      "examples": [
                                        "How many kilos can I take on booking TN-48213?"
                                      ]
                                    },
                                    "success_criteria": {
                                      "minItems": 1,
                                      "maxItems": 12,
                                      "type": "array",
                                      "items": {
                                        "type": "string",
                                        "minLength": 1,
                                        "maxLength": 500
                                      },
                                      "description": "What a pass looks like: 1 to 12 lines, each up to 500 characters. Every one must be met.",
                                      "examples": [
                                        [
                                          "Says 7 kg of cabin baggage."
                                        ]
                                      ]
                                    },
                                    "must_never": {
                                      "default": [],
                                      "maxItems": 12,
                                      "type": "array",
                                      "items": {
                                        "type": "string",
                                        "minLength": 1,
                                        "maxLength": 500
                                      },
                                      "description": "What must never happen: up to 12 lines, each up to 500 characters. Any one fails the test.",
                                      "examples": [
                                        [
                                          "Promises a refund."
                                        ]
                                      ]
                                    },
                                    "tool_results": {
                                      "description": "What each tool answers in this test, as any JSON, at most 20: a declared tool by its name, and a tool of an MCP server as <server>.<tool> (the server's slug), since a test never runs one for real unless the server marks it read-only. A tool with none answers an error.",
                                      "examples": [
                                        {
                                          "get_booking": {
                                            "cabin_kg": 7
                                          }
                                        }
                                      ],
                                      "type": "object",
                                      "propertyNames": {
                                        "type": "string",
                                        "pattern": "^(?!mcp__)(?:[a-z][a-z0-9_]{0,63}|[a-z][a-z0-9-]{0,39}\\.[A-Za-z0-9_.-]{1,128})$"
                                      },
                                      "additionalProperties": {}
                                    },
                                    "approves": {
                                      "description": "true: the test user says yes to each approval for a tool of one of the deployment's own MCP servers, which in a test plays its tool_results entry or does not run. Absent or false: it says no to every approval. Anything else that waits for a yes is always declined.",
                                      "examples": [
                                        true
                                      ],
                                      "type": "boolean"
                                    }
                                  },
                                  "required": [
                                    "name",
                                    "persona",
                                    "goal",
                                    "success_criteria",
                                    "must_never"
                                  ],
                                  "description": "The scenario as it was played."
                                },
                                "verdict": {
                                  "type": "string",
                                  "enum": [
                                    "passed",
                                    "failed",
                                    "error"
                                  ],
                                  "description": "`passed`: every line of success met and nothing it must never do. `failed`: not so. `error`: it could not be played to the end."
                                },
                                "reason": {
                                  "type": "string",
                                  "description": "Why, in a sentence or two."
                                },
                                "criteria": {
                                  "type": "array",
                                  "items": {
                                    "type": "object",
                                    "properties": {
                                      "criterion": {
                                        "type": "string",
                                        "description": "One line of what a pass looks like."
                                      },
                                      "met": {
                                        "type": "boolean",
                                        "description": "Whether the conversation met it."
                                      },
                                      "evidence": {
                                        "type": "string",
                                        "description": "Why the grader says so, from the conversation."
                                      }
                                    },
                                    "required": [
                                      "criterion",
                                      "met",
                                      "evidence"
                                    ]
                                  },
                                  "description": "Each line of success, graded."
                                },
                                "must_never": {
                                  "type": "array",
                                  "items": {
                                    "type": "object",
                                    "properties": {
                                      "rule": {
                                        "type": "string",
                                        "description": "One line of what must never happen."
                                      },
                                      "violated": {
                                        "type": "boolean",
                                        "description": "Whether it happened."
                                      },
                                      "evidence": {
                                        "type": "string",
                                        "description": "Why the grader says so, from the conversation."
                                      }
                                    },
                                    "required": [
                                      "rule",
                                      "violated",
                                      "evidence"
                                    ]
                                  },
                                  "description": "Each thing it must never do, graded."
                                },
                                "approvals_asked": {
                                  "type": "array",
                                  "items": {
                                    "type": "object",
                                    "properties": {
                                      "kind": {
                                        "type": "string",
                                        "description": "The kind of ask Bash raised, such as `hands_approval`, `credit_approval` or `tool_permission`."
                                      },
                                      "category": {
                                        "type": "string",
                                        "enum": [
                                          "payment",
                                          "account_action",
                                          "connect_app",
                                          "action",
                                          "custom"
                                        ],
                                        "description": "What it would have done: a `payment`, an `account_action`, `connect_app`, another `action`, or `custom`."
                                      },
                                      "summary": {
                                        "type": "string",
                                        "description": "What it asked to do, in its words."
                                      },
                                      "decision": {
                                        "type": "string",
                                        "enum": [
                                          "denied",
                                          "approved"
                                        ],
                                        "description": "What the test user said. It denies anything that would act for it, so a test never moves money or changes an account; a test with approves: true approves the tools of the deployment's own MCP servers, which a test plays from its tool_results or does not run."
                                      }
                                    },
                                    "required": [
                                      "kind",
                                      "category",
                                      "summary",
                                      "decision"
                                    ]
                                  },
                                  "description": "What Bash asked the test user's yes for, and what it said."
                                },
                                "transcript": {
                                  "type": "array",
                                  "items": {
                                    "type": "object",
                                    "properties": {
                                      "role": {
                                        "type": "string",
                                        "enum": [
                                          "customer",
                                          "bash",
                                          "note"
                                        ],
                                        "description": "Who said it: `customer` (the test user), `bash`, or a `note` on what happened (work started, a tool called)."
                                      },
                                      "text": {
                                        "type": "string",
                                        "description": "What was said, or what happened."
                                      }
                                    },
                                    "required": [
                                      "role",
                                      "text"
                                    ]
                                  },
                                  "description": "The conversation, line by line."
                                },
                                "conversation_id": {
                                  "anyOf": [
                                    {
                                      "type": "string"
                                    },
                                    {
                                      "type": "null"
                                    }
                                  ],
                                  "description": "The test conversation; null when it never started."
                                },
                                "cost_usd": {
                                  "type": "number",
                                  "description": "What playing it cost, in billed US dollars."
                                }
                              },
                              "required": [
                                "object",
                                "scenario_id",
                                "scenario",
                                "verdict",
                                "reason",
                                "criteria",
                                "must_never",
                                "approvals_asked",
                                "transcript",
                                "conversation_id",
                                "cost_usd"
                              ]
                            }
                          }
                        },
                        "required": [
                          "id",
                          "object",
                          "deployment_id",
                          "version",
                          "status",
                          "error_code",
                          "scenario_count",
                          "passed_count",
                          "resumes",
                          "promoted",
                          "became_default",
                          "cost_usd",
                          "created_at",
                          "started_at",
                          "finished_at"
                        ]
                      },
                      "description": "The items on this page."
                    },
                    "next_cursor": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Send it as `cursor` for the next page; null on the last page."
                    }
                  },
                  "required": [
                    "data",
                    "next_cursor"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/test-runs/{test_run_id}": {
      "get": {
        "operationId": "getTestRunsByTestRunId",
        "summary": "Pass or fail per scenario, the conversation and the judge's reason.",
        "tags": [
          "Tests"
        ],
        "x-vestra-line": "test",
        "x-vestra-scope": "setup",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "test_run_id",
            "in": "path",
            "required": true,
            "description": "The test run's id (`trun_...`).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "The test run's id.",
                      "examples": [
                        "trun_8f2k"
                      ]
                    },
                    "object": {
                      "type": "string",
                      "const": "test_run",
                      "description": "Always `test_run`."
                    },
                    "deployment_id": {
                      "type": "string",
                      "description": "The deployment it tests."
                    },
                    "version": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991,
                      "description": "The version it tests."
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "queued",
                        "running",
                        "passed",
                        "failed",
                        "error"
                      ],
                      "description": "`queued` or `running` while it plays. `passed`: every scenario passed. `failed`: one or more did not. `error`: it could not finish, as `error_code` says."
                    },
                    "error_code": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Why it ended in `error`: `interrupted` (a restart stopped it too often), `test_wallet_empty`, `judge_unreadable` (the grader's answer could not be read) or `internal`. Null otherwise."
                    },
                    "scenario_count": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991,
                      "description": "How many scenarios it plays."
                    },
                    "passed_count": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991,
                      "description": "How many have passed so far."
                    },
                    "resumes": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991,
                      "description": "How many times a restart interrupted it and it played on from where it was, at most 2."
                    },
                    "promoted": {
                      "anyOf": [
                        {
                          "type": "object",
                          "properties": {
                            "mode": {
                              "type": "string",
                              "enum": [
                                "live",
                                "test"
                              ],
                              "description": "The mode the version went live in."
                            },
                            "version": {
                              "type": "integer",
                              "minimum": -9007199254740991,
                              "maximum": 9007199254740991,
                              "description": "The version that went live."
                            }
                          },
                          "required": [
                            "mode",
                            "version"
                          ]
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "What its pass promoted, for an apply that promotes after its tests; null when it promoted nothing (none asked, refused, or it did not pass)."
                    },
                    "became_default": {
                      "type": "boolean",
                      "description": "True when that promotion made the deployment the company's default: an ask with no deployment now reaches it."
                    },
                    "cost_usd": {
                      "type": "number",
                      "description": "What the run cost, in billed US dollars."
                    },
                    "created_at": {
                      "type": "string",
                      "description": "When it was asked for, as an ISO 8601 date and time in UTC."
                    },
                    "started_at": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "When it began to play; null while queued."
                    },
                    "finished_at": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "When it ended; null while it plays."
                    },
                    "results": {
                      "description": "Each scenario's result, on GET /v1/test-runs/{test_run_id}; absent in lists.",
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "object": {
                            "type": "string",
                            "const": "test_result",
                            "description": "Always `test_result`."
                          },
                          "scenario_id": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "The scenario it played; null when the scenario was deleted since."
                          },
                          "scenario": {
                            "type": "object",
                            "properties": {
                              "name": {
                                "type": "string",
                                "minLength": 1,
                                "maxLength": 120,
                                "description": "Its name, 1 to 120 characters.",
                                "examples": [
                                  "Bag allowance"
                                ]
                              },
                              "persona": {
                                "type": "string",
                                "minLength": 1,
                                "maxLength": 2000,
                                "description": "Who the test user is, in a few sentences, up to 2,000 characters.",
                                "examples": [
                                  "A first-time flyer, anxious, on a phone."
                                ]
                              },
                              "goal": {
                                "type": "string",
                                "minLength": 1,
                                "maxLength": 2000,
                                "description": "What the test user wants, in their words, up to 2,000 characters.",
                                "examples": [
                                  "How many kilos can I take on booking TN-48213?"
                                ]
                              },
                              "success_criteria": {
                                "minItems": 1,
                                "maxItems": 12,
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 500
                                },
                                "description": "What a pass looks like: 1 to 12 lines, each up to 500 characters. Every one must be met.",
                                "examples": [
                                  [
                                    "Says 7 kg of cabin baggage."
                                  ]
                                ]
                              },
                              "must_never": {
                                "default": [],
                                "maxItems": 12,
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 500
                                },
                                "description": "What must never happen: up to 12 lines, each up to 500 characters. Any one fails the test.",
                                "examples": [
                                  [
                                    "Promises a refund."
                                  ]
                                ]
                              },
                              "tool_results": {
                                "description": "What each tool answers in this test, as any JSON, at most 20: a declared tool by its name, and a tool of an MCP server as <server>.<tool> (the server's slug), since a test never runs one for real unless the server marks it read-only. A tool with none answers an error.",
                                "examples": [
                                  {
                                    "get_booking": {
                                      "cabin_kg": 7
                                    }
                                  }
                                ],
                                "type": "object",
                                "propertyNames": {
                                  "type": "string",
                                  "pattern": "^(?!mcp__)(?:[a-z][a-z0-9_]{0,63}|[a-z][a-z0-9-]{0,39}\\.[A-Za-z0-9_.-]{1,128})$"
                                },
                                "additionalProperties": {}
                              },
                              "approves": {
                                "description": "true: the test user says yes to each approval for a tool of one of the deployment's own MCP servers, which in a test plays its tool_results entry or does not run. Absent or false: it says no to every approval. Anything else that waits for a yes is always declined.",
                                "examples": [
                                  true
                                ],
                                "type": "boolean"
                              }
                            },
                            "required": [
                              "name",
                              "persona",
                              "goal",
                              "success_criteria",
                              "must_never"
                            ],
                            "description": "The scenario as it was played."
                          },
                          "verdict": {
                            "type": "string",
                            "enum": [
                              "passed",
                              "failed",
                              "error"
                            ],
                            "description": "`passed`: every line of success met and nothing it must never do. `failed`: not so. `error`: it could not be played to the end."
                          },
                          "reason": {
                            "type": "string",
                            "description": "Why, in a sentence or two."
                          },
                          "criteria": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "criterion": {
                                  "type": "string",
                                  "description": "One line of what a pass looks like."
                                },
                                "met": {
                                  "type": "boolean",
                                  "description": "Whether the conversation met it."
                                },
                                "evidence": {
                                  "type": "string",
                                  "description": "Why the grader says so, from the conversation."
                                }
                              },
                              "required": [
                                "criterion",
                                "met",
                                "evidence"
                              ]
                            },
                            "description": "Each line of success, graded."
                          },
                          "must_never": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "rule": {
                                  "type": "string",
                                  "description": "One line of what must never happen."
                                },
                                "violated": {
                                  "type": "boolean",
                                  "description": "Whether it happened."
                                },
                                "evidence": {
                                  "type": "string",
                                  "description": "Why the grader says so, from the conversation."
                                }
                              },
                              "required": [
                                "rule",
                                "violated",
                                "evidence"
                              ]
                            },
                            "description": "Each thing it must never do, graded."
                          },
                          "approvals_asked": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "kind": {
                                  "type": "string",
                                  "description": "The kind of ask Bash raised, such as `hands_approval`, `credit_approval` or `tool_permission`."
                                },
                                "category": {
                                  "type": "string",
                                  "enum": [
                                    "payment",
                                    "account_action",
                                    "connect_app",
                                    "action",
                                    "custom"
                                  ],
                                  "description": "What it would have done: a `payment`, an `account_action`, `connect_app`, another `action`, or `custom`."
                                },
                                "summary": {
                                  "type": "string",
                                  "description": "What it asked to do, in its words."
                                },
                                "decision": {
                                  "type": "string",
                                  "enum": [
                                    "denied",
                                    "approved"
                                  ],
                                  "description": "What the test user said. It denies anything that would act for it, so a test never moves money or changes an account; a test with approves: true approves the tools of the deployment's own MCP servers, which a test plays from its tool_results or does not run."
                                }
                              },
                              "required": [
                                "kind",
                                "category",
                                "summary",
                                "decision"
                              ]
                            },
                            "description": "What Bash asked the test user's yes for, and what it said."
                          },
                          "transcript": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "role": {
                                  "type": "string",
                                  "enum": [
                                    "customer",
                                    "bash",
                                    "note"
                                  ],
                                  "description": "Who said it: `customer` (the test user), `bash`, or a `note` on what happened (work started, a tool called)."
                                },
                                "text": {
                                  "type": "string",
                                  "description": "What was said, or what happened."
                                }
                              },
                              "required": [
                                "role",
                                "text"
                              ]
                            },
                            "description": "The conversation, line by line."
                          },
                          "conversation_id": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "The test conversation; null when it never started."
                          },
                          "cost_usd": {
                            "type": "number",
                            "description": "What playing it cost, in billed US dollars."
                          }
                        },
                        "required": [
                          "object",
                          "scenario_id",
                          "scenario",
                          "verdict",
                          "reason",
                          "criteria",
                          "must_never",
                          "approvals_asked",
                          "transcript",
                          "conversation_id",
                          "cost_usd"
                        ]
                      }
                    }
                  },
                  "required": [
                    "id",
                    "object",
                    "deployment_id",
                    "version",
                    "status",
                    "error_code",
                    "scenario_count",
                    "passed_count",
                    "resumes",
                    "promoted",
                    "became_default",
                    "cost_usd",
                    "created_at",
                    "started_at",
                    "finished_at"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/users/{user_id}/warm": {
      "post": {
        "operationId": "postUsersByUserIdWarm",
        "summary": "Wake the user's computer now (for example when they open your app), so their next task starts without waiting. Answers 200 when it is already up and 202 while it wakes. At most 10 computers wake at once per company (429 warm_limit), and a second call for one user within a minute rides the first. keep_ms keeps it awake that long once it is up, up to two minutes; calling again extends it.",
        "tags": [
          "Computer setup"
        ],
        "x-vestra-line": "users",
        "x-vestra-scope": "runtime",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "user_id",
            "in": "path",
            "required": true,
            "description": "Your own id for the user, as you named them.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "user_id": {
                      "type": "string",
                      "description": "Your id for the user whose computer it is."
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "ready",
                        "waking"
                      ],
                      "description": "`ready`: the computer is up. `waking`: a wake started now; their next task starts without waiting once it lands."
                    }
                  },
                  "required": [
                    "user_id",
                    "status"
                  ]
                }
              }
            }
          },
          "202": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "user_id": {
                      "type": "string",
                      "description": "Your id for the user whose computer it is."
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "ready",
                        "waking"
                      ],
                      "description": "`ready`: the computer is up. `waking`: a wake started now; their next task starts without waiting once it lands."
                    }
                  },
                  "required": [
                    "user_id",
                    "status"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "keep_ms": {
                    "description": "Keep the computer awake this long once it is up, in ms: 1000 to 120000. Absent: it sleeps again soon after if nothing uses it. Calling warm again extends it.",
                    "type": "integer",
                    "minimum": 1000,
                    "maximum": 120000
                  }
                },
                "additionalProperties": false
              }
            }
          }
        }
      }
    },
    "/v1/users/{user_id}/browser/fetch": {
      "post": {
        "operationId": "postUsersByUserIdBrowserFetch",
        "summary": "Open one page in a background tab of the user's own browser, with no model, and get back the bodies of the page's own data calls that match capture. Only on sites the user's deployment lists in browser.allowed_domains (403 domain_not_allowed), and never on a page in its browser.blocked_paths, such as a payment page (403 page_blocked). Wakes the computer when it sleeps. Answers as soon as every required capture has its responses, with timings; 409 browser_in_use while a person drives the browser, 409 browser_busy past four at once; 504 timeout carries what came back in partial. frames returns small pictures of the tab at each milestone. A page_fetch step calls one of the deployment's sites from inside the page, as the page's own script would; keep_open_ms keeps the tab for the next fetch, which sends no url (409 no_open_tab when none is kept).",
        "tags": [
          "Computer setup"
        ],
        "x-vestra-line": "users",
        "x-vestra-scope": "runtime",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "user_id",
            "in": "path",
            "required": true,
            "description": "Your own id for the user, as you named them.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "final_url": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The page's address when the fetch ended, after any redirects and steps; null if it never opened."
                    },
                    "elapsed_ms": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991,
                      "description": "How long the whole call took, in ms, waking included."
                    },
                    "woke": {
                      "type": "boolean",
                      "description": "true when the computer was asleep and this call woke it."
                    },
                    "timings": {
                      "type": "object",
                      "properties": {
                        "wake_ms": {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991,
                          "description": "How long waking the computer took: 0 when it was up."
                        },
                        "nav_ms": {
                          "anyOf": [
                            {
                              "type": "integer",
                              "minimum": -9007199254740991,
                              "maximum": 9007199254740991
                            },
                            {
                              "type": "null"
                            }
                          ],
                          "description": "When the page started showing (its navigation committed); null if it never did, or when the fetch ran on a kept tab with nothing to open."
                        },
                        "first_capture_ms": {
                          "anyOf": [
                            {
                              "type": "integer",
                              "minimum": -9007199254740991,
                              "maximum": 9007199254740991
                            },
                            {
                              "type": "null"
                            }
                          ],
                          "description": "When the first kept response finished; null if none did."
                        },
                        "done_ms": {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991,
                          "description": "When the computer finished the fetch."
                        }
                      },
                      "required": [
                        "wake_ms",
                        "nav_ms",
                        "first_capture_ms",
                        "done_ms"
                      ],
                      "description": "Where the time went, each in ms after the call arrived."
                    },
                    "captures": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "match": {
                            "type": "string",
                            "description": "The capture this response answers, or the page_fetch step's capture_as."
                          },
                          "url": {
                            "type": "string",
                            "description": "The full address of the response."
                          },
                          "status": {
                            "type": "integer",
                            "minimum": -9007199254740991,
                            "maximum": 9007199254740991,
                            "description": "Its HTTP status."
                          },
                          "content_type": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "Its content type, such as application/json; null when it had none."
                          },
                          "body": {
                            "type": "string",
                            "description": "Its body, as text."
                          },
                          "truncated": {
                            "type": "boolean",
                            "description": "true when the body was longer than max_bytes, or the fetch had kept 8000000 bytes in all, and it was cut. With sse \"last\": true when the event kept is not the stream's last one (the last was too long, or the stream ended partway through it)."
                          },
                          "at_ms": {
                            "type": "integer",
                            "minimum": -9007199254740991,
                            "maximum": 9007199254740991,
                            "description": "When it finished, in ms after the call arrived."
                          }
                        },
                        "required": [
                          "match",
                          "url",
                          "status",
                          "content_type",
                          "body",
                          "truncated",
                          "at_ms"
                        ]
                      },
                      "description": "Every response kept, in the order they finished."
                    },
                    "frames": {
                      "description": "With `frames` asked: the pictures, in the order they were taken. A frame that would have slowed the answer is left out.",
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "label": {
                            "type": "string",
                            "description": "Which moment: `navigated`, `captured <match>`, `after <step>` or `done`.",
                            "examples": [
                              "navigated"
                            ]
                          },
                          "at_ms": {
                            "type": "integer",
                            "minimum": -9007199254740991,
                            "maximum": 9007199254740991,
                            "description": "When it was taken, in ms after the call arrived."
                          },
                          "page_url": {
                            "type": "string",
                            "description": "The page's address when it was taken; always on an allowed site."
                          },
                          "jpeg_base64": {
                            "type": "string",
                            "description": "The picture, a JPEG, as base64."
                          }
                        },
                        "required": [
                          "label",
                          "at_ms",
                          "page_url",
                          "jpeg_base64"
                        ]
                      }
                    },
                    "step": {
                      "description": "With a `timeout`: where the fetch was when the time ran out: `navigate`, a step by its number and op such as `2 scroll`, or `captures` when every step was done and it was waiting for the required captures.",
                      "examples": [
                        "2 scroll"
                      ],
                      "type": "string"
                    },
                    "challenge": {
                      "description": "`turnstile`: the page called Cloudflare's Turnstile check.",
                      "type": "string",
                      "const": "turnstile"
                    }
                  },
                  "required": [
                    "final_url",
                    "elapsed_ms",
                    "woke",
                    "timings",
                    "captures"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "url": {
                    "description": "The page to open, http or https, on a site the user's deployment allows (browser.allowed_domains). Absent: the steps run on the tab an earlier fetch kept open (keep_open_ms), as it is; 409 no_open_tab when none is kept.",
                    "examples": [
                      "https://www.ixigo.com/search/result/flight?from=DEL&to=GOI&date=06112026&adults=4&class=e"
                    ],
                    "type": "string",
                    "maxLength": 4000,
                    "format": "uri"
                  },
                  "capture": {
                    "description": "The responses to keep, up to 10. The fetch answers as soon as every step is done and every required capture has its responses. Absent: none, for a fetch made of page_fetch steps.",
                    "maxItems": 10,
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "match": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 500,
                          "description": "Part of the address of a response to keep, such as `/api/v3/search`: a finished response whose address contains it is kept. Ending in `$`, it must end the path instead (the query aside), so `/v3/services$` keeps `/v3/services` and not `/v3/services/meta/105`.",
                          "examples": [
                            "/flights/v2/search/stream"
                          ]
                        },
                        "required": {
                          "description": "Whether the fetch waits for it. Default true: the fetch answers as soon as every required capture has min_count responses. false: kept if it comes before then, never waited for.",
                          "type": "boolean"
                        },
                        "min_count": {
                          "description": "How many responses a required capture waits for, 1 to 10. Default 1. A page that loads its second page by itself (hotels) needs 2.",
                          "type": "integer",
                          "minimum": 1,
                          "maximum": 10
                        },
                        "max_count": {
                          "description": "The most responses it keeps, 1 to 10. Default min_count, or 1.",
                          "type": "integer",
                          "minimum": 1,
                          "maximum": 10
                        },
                        "max_bytes": {
                          "description": "The most bytes of each body to keep, up to 1048576, or up to 4194304 with sse \"last\". Default 524288; a longer body comes back cut, with truncated true.",
                          "type": "integer",
                          "minimum": 1,
                          "maximum": 4194304
                        },
                        "sse": {
                          "description": "For an event stream (text/event-stream) whose every event is the whole answer so far: \"last\" keeps only its last complete event, as a stream of that one event, and max_bytes is that event's limit. When the last event is past max_bytes, or the stream ends partway through one, the newest complete event that fits comes back instead, with truncated true. A body that is not an event stream is kept as it is. Absent: the body as it came.",
                          "type": "string",
                          "enum": [
                            "last"
                          ]
                        }
                      },
                      "required": [
                        "match"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "steps": {
                    "description": "What to do on the page after it opens, in order, up to 20. Absent: nothing; the page is only opened.",
                    "maxItems": 20,
                    "type": "array",
                    "items": {
                      "anyOf": [
                        {
                          "type": "object",
                          "properties": {
                            "op": {
                              "type": "string",
                              "const": "click",
                              "description": "Click one element, found by what a screen reader calls it."
                            },
                            "role": {
                              "description": "Its role, such as button, link, tab or option.",
                              "examples": [
                                "button"
                              ],
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 60
                            },
                            "name": {
                              "description": "Its whole accessible name, in any case, such as Search.",
                              "examples": [
                                "Search"
                              ],
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 500
                            },
                            "text": {
                              "description": "Words its accessible name contains, in any case, when the whole name is not known.",
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 500
                            },
                            "optional": {
                              "description": "true: the element may not be there (a popup that does not always show). The step looks once, clicks it if it is there, and goes on quietly if not, so put it where the popup is already up, such as after the steps that wait for the results. Absent: the step waits for it as long as the fetch may.",
                              "type": "boolean"
                            },
                            "within_ms": {
                              "description": "With optional: look for it this long, 1 to 10000 ms, before going on without it (a popup that shows a moment after the page).",
                              "type": "integer",
                              "minimum": 1,
                              "maximum": 10000
                            },
                            "nth": {
                              "description": "Which match, 1 for the first.",
                              "examples": [
                                3
                              ],
                              "type": "integer",
                              "minimum": 1,
                              "maximum": 50
                            },
                            "near_text": {
                              "description": "The first match after this text, or after these texts in turn with no match between them.",
                              "anyOf": [
                                {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 500
                                },
                                {
                                  "minItems": 1,
                                  "maxItems": 4,
                                  "type": "array",
                                  "items": {
                                    "type": "string",
                                    "minLength": 1,
                                    "maxLength": 500
                                  }
                                }
                              ]
                            }
                          },
                          "required": [
                            "op"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "op": {
                              "type": "string",
                              "const": "type",
                              "description": "Type into one box, found by what a screen reader calls it: the box is focused, what it holds is replaced, and the text goes in as a person's typing does, so the page's own suggestions come up."
                            },
                            "role": {
                              "description": "Its role, such as textbox, combobox or searchbox. With no name, the first box of that role on the page. With neither role nor name, the box that has focus now, such as one a click just opened: the step waits for a box a person could type into to have focus.",
                              "examples": [
                                "searchbox"
                              ],
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 60
                            },
                            "name": {
                              "description": "Its whole accessible name, in any case.",
                              "examples": [
                                "Enter Origin"
                              ],
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 500
                            },
                            "text": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 200,
                              "description": "What to type, 1 to 200 characters.",
                              "examples": [
                                "London"
                              ]
                            },
                            "submit": {
                              "description": "true: press Enter after typing. Absent: no Enter; pick a suggestion with a click step after a wait_for.",
                              "type": "boolean"
                            },
                            "optional": {
                              "description": "true: the box may not be there. The step looks once, types if it is there, and goes on quietly if not. Absent: the step waits for it as long as the fetch may.",
                              "type": "boolean"
                            }
                          },
                          "required": [
                            "op",
                            "text"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "op": {
                              "type": "string",
                              "const": "scroll",
                              "description": "Scroll down one screen at a time."
                            },
                            "times": {
                              "type": "integer",
                              "minimum": 1,
                              "maximum": 20,
                              "description": "How many screens to scroll, 1 to 20."
                            }
                          },
                          "required": [
                            "op",
                            "times"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "op": {
                              "type": "string",
                              "const": "wait_for",
                              "description": "Wait for a response to finish."
                            },
                            "match": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 500,
                              "description": "Part of the address of the response to wait for, read as a capture reads it (`$` ends the path). Only a response that finishes after the step before this one started counts."
                            }
                          },
                          "required": [
                            "op",
                            "match"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "op": {
                              "type": "string",
                              "const": "page_fetch",
                              "description": "Call one of the deployment's sites from inside the page, as the page's own script would (its cookie and CORS rules apply). The answer is a capture whose match is capture_as. Off browser.allowed_domains: 403 domain_not_allowed; on browser.blocked_paths: 403 page_blocked. No redirect is followed."
                            },
                            "url": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 4000,
                              "description": "What to call: a path on the page's own site, or a full https address on one of the deployment's sites.",
                              "examples": [
                                "/hotels-autocompleter/api/v2/results?query=Anjuna&size=10&v=3"
                              ]
                            },
                            "method": {
                              "description": "GET or POST. Default GET.",
                              "type": "string",
                              "enum": [
                                "GET",
                                "POST"
                              ]
                            },
                            "headers": {
                              "description": "Headers to send, up to 20, such as a POST's content-type. The browser adds the page's cookies itself.",
                              "type": "object",
                              "propertyNames": {
                                "type": "string",
                                "minLength": 1,
                                "maxLength": 100
                              },
                              "additionalProperties": {
                                "type": "string",
                                "maxLength": 2000
                              }
                            },
                            "body": {
                              "description": "A POST's body, as text: up to 100000 characters.",
                              "type": "string",
                              "maxLength": 100000
                            },
                            "capture_as": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 60,
                              "description": "The name its answer carries in captures, as its match.",
                              "examples": [
                                "places"
                              ]
                            },
                            "max_bytes": {
                              "description": "The most bytes of the answer to keep, up to 1048576. Default 524288; a longer one comes back cut, with truncated true.",
                              "type": "integer",
                              "minimum": 1,
                              "maximum": 1048576
                            }
                          },
                          "required": [
                            "op",
                            "url",
                            "capture_as"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "properties": {
                            "op": {
                              "type": "string",
                              "const": "page_fetch",
                              "description": "Several page_fetch calls at once, each read and checked as a single page_fetch is."
                            },
                            "calls": {
                              "minItems": 1,
                              "maxItems": 10,
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "url": {
                                    "type": "string",
                                    "minLength": 1,
                                    "maxLength": 4000,
                                    "description": "What to call: a path on the page's own site, or a full https address on one of the deployment's sites.",
                                    "examples": [
                                      "/hotels-autocompleter/api/v2/results?query=Anjuna&size=10&v=3"
                                    ]
                                  },
                                  "method": {
                                    "description": "GET or POST. Default GET.",
                                    "type": "string",
                                    "enum": [
                                      "GET",
                                      "POST"
                                    ]
                                  },
                                  "headers": {
                                    "description": "Headers to send, up to 20, such as a POST's content-type. The browser adds the page's cookies itself.",
                                    "type": "object",
                                    "propertyNames": {
                                      "type": "string",
                                      "minLength": 1,
                                      "maxLength": 100
                                    },
                                    "additionalProperties": {
                                      "type": "string",
                                      "maxLength": 2000
                                    }
                                  },
                                  "body": {
                                    "description": "A POST's body, as text: up to 100000 characters.",
                                    "type": "string",
                                    "maxLength": 100000
                                  },
                                  "capture_as": {
                                    "type": "string",
                                    "minLength": 1,
                                    "maxLength": 60,
                                    "description": "The name its answer carries in captures, as its match.",
                                    "examples": [
                                      "places"
                                    ]
                                  },
                                  "max_bytes": {
                                    "description": "The most bytes of the answer to keep, up to 1048576. Default 524288; a longer one comes back cut, with truncated true.",
                                    "type": "integer",
                                    "minimum": 1,
                                    "maximum": 1048576
                                  }
                                },
                                "required": [
                                  "url",
                                  "capture_as"
                                ],
                                "additionalProperties": false,
                                "description": "One call of a batch page_fetch, read as a single page_fetch is."
                              },
                              "description": "Up to 10 calls, run at once, so the step costs about its slowest. One refused call refuses the step before any runs."
                            }
                          },
                          "required": [
                            "op",
                            "calls"
                          ],
                          "additionalProperties": false
                        }
                      ],
                      "description": "One thing to do on the page after it opens, in order: click, type, scroll, wait_for or page_fetch. No screenshots and no model: elements are found in the accessibility tree."
                    }
                  },
                  "frames": {
                    "description": "Small pictures of the tab as it works: when the page first shows, when each required capture arrives, after each step, every 0.7 s, and at the end. At most 6 and about 400 KB in all. Absent: none.",
                    "type": "object",
                    "properties": {
                      "width": {
                        "description": "How wide each frame is, in pixels: 160 to 1280. Default 640.",
                        "type": "integer",
                        "minimum": 160,
                        "maximum": 1280
                      },
                      "settle_ms": {
                        "description": "Once every required capture is in, keep taking frames, labelled `results`, about every 170 ms for this long while the page draws what came, then answer: 0 to 700 ms. A page can blank for a moment as it draws; a run of frames catches the drawn one. Default 0: answer at once, and the last frame may still show the page loading.",
                        "type": "integer",
                        "minimum": 0,
                        "maximum": 700
                      }
                    },
                    "additionalProperties": false
                  },
                  "timeout_ms": {
                    "description": "How long the page may take, from when it starts opening, in ms: 1000 to 20000. Default 8000. Waking the computer comes on top.",
                    "type": "integer",
                    "minimum": 1000,
                    "maximum": 20000
                  },
                  "grace_ms": {
                    "description": "Once every required capture has its min_count, wait up to this long for every capture to fill to its max_count, optional ones too, then answer with what came: 0 to 3000 ms. Default 0: answer at once.",
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 3000
                  },
                  "keep_open_ms": {
                    "description": "Keep this fetch's tab open on its page this long after it answers, with the computer awake, so the next fetch with no url runs there at once: 0 to 600000 ms. Default 0.",
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 600000
                  },
                  "tab": {
                    "description": "Which kept tab: keep_open_ms keeps this tab under the name, and a fetch with no url takes the tab of that name. Up to 4 are kept. Default `default`.",
                    "examples": [
                      "stays"
                    ],
                    "type": "string",
                    "pattern": "^[a-z0-9][a-z0-9_-]{0,39}$"
                  },
                  "tag": {
                    "description": "Your label for this fetch; the browser watch names its tab with it.",
                    "type": "string",
                    "pattern": "^[A-Za-z0-9_.:-]{1,64}$"
                  },
                  "front": {
                    "description": "A hand-off the person finishes themselves, such as a sign-in: the tab's window opens in front of theirs, maximized, with the keyboard, and with keep_open_ms stays there for them. Default false: behind their window.",
                    "type": "boolean"
                  },
                  "front_device": {
                    "description": "With front: `phone` (default) or `desktop`, the site's desktop page, as the other fetches see it, at a phone's shape (440 wide, as high as the window): a sign-in service's tab it opens draws into the same part of the screen, so a session's screen shows one rectangle whatever is in front.",
                    "type": "string",
                    "enum": [
                      "phone",
                      "desktop"
                    ]
                  },
                  "front_crop": {
                    "description": "On a hand-off (front, or a fetch with no url on its kept tab): a session's screen shows only this element of the page, such as a site's sign-in dialog at a phone's size. From a front fetch's start until the element is on the page, the screen answers `crop_pending` instead of a crop, for up to 20 seconds; past that it shows the page as before.",
                    "type": "object",
                    "properties": {
                      "role": {
                        "description": "The element's accessibility role, such as `dialog`.",
                        "examples": [
                          "dialog"
                        ],
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 40
                      },
                      "name": {
                        "description": "Its accessible name, exactly.",
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 200
                      },
                      "text": {
                        "description": "Words its accessible name contains.",
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 200
                      }
                    },
                    "additionalProperties": false
                  },
                  "stage": {
                    "description": "In front, in one kept tab (`tab`), shown alone in the watch.",
                    "type": "boolean"
                  },
                  "private": {
                    "description": "Never shown in the browser watch, and no frames taken: a person's own account page, say.",
                    "type": "boolean"
                  }
                },
                "additionalProperties": false
              }
            }
          }
        }
      }
    },
    "/v1/routines": {
      "post": {
        "operationId": "postRoutines",
        "summary": "Create one: what to ask, and when: every (plain words such as \"weekday at 08:00\", read in the user's time zone), a cron schedule, or on \"call\" (your system posts to its trigger_url). For a user, or with no user_id for the company's own Bash. Each run is a message in the routine's conversation.",
        "tags": [
          "Routines"
        ],
        "x-vestra-line": "routines",
        "x-vestra-scope": "runtime",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 255
            },
            "description": "Send the same key to retry this call safely for 24 hours."
          }
        ],
        "responses": {
          "201": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "The routine's id.",
                      "examples": [
                        "rtn_8f2k"
                      ]
                    },
                    "object": {
                      "type": "string",
                      "const": "routine",
                      "description": "Always `routine`."
                    },
                    "user_id": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Your id for the user whose Bash runs it; null for your company's own Bash."
                    },
                    "conversation_id": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The conversation each run posts into, named or made when the routine was; null for a routine not made through the API."
                    },
                    "name": {
                      "type": "string",
                      "description": "Its name."
                    },
                    "ask": {
                      "type": "string",
                      "description": "What Bash is asked on every run."
                    },
                    "kind": {
                      "type": "string",
                      "enum": [
                        "schedule",
                        "trigger",
                        "app_event"
                      ],
                      "description": "`schedule`: it runs on its schedule. `trigger`: it runs when your system posts to `trigger_url`. `app_event`: an event in a connected app runs it."
                    },
                    "schedule": {
                      "anyOf": [
                        {
                          "type": "object",
                          "properties": {
                            "every": {
                              "anyOf": [
                                {
                                  "type": "string"
                                },
                                {
                                  "type": "null"
                                }
                              ],
                              "description": "The plain words it was given; null for a cron."
                            },
                            "cron": {
                              "type": "string",
                              "description": "The schedule as cron, worked out from `every` when it was given in words."
                            },
                            "timezone": {
                              "type": "string",
                              "description": "The zone it runs in, an IANA name."
                            }
                          },
                          "required": [
                            "every",
                            "cron",
                            "timezone"
                          ]
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "When it runs; null for one that runs on a call."
                    },
                    "trigger": {
                      "anyOf": [
                        {
                          "type": "object",
                          "properties": {
                            "filters": {
                              "anyOf": [
                                {
                                  "type": "object",
                                  "propertyNames": {
                                    "type": "string"
                                  },
                                  "additionalProperties": {}
                                },
                                {
                                  "type": "null"
                                }
                              ],
                              "description": "What a payload must carry for it to run; null: any payload."
                            }
                          },
                          "required": [
                            "filters"
                          ]
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "For one that runs on a call, what it listens for; null for one on a schedule."
                    },
                    "trigger_url": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "For one that runs on a call: POST here, with your key and any JSON object, to run it. Null otherwise."
                    },
                    "enabled": {
                      "type": "boolean",
                      "description": "false while it is paused."
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "active",
                        "completed",
                        "failed"
                      ],
                      "description": "`active`: it runs as it should. `completed`: it has finished and will not run again. `failed`: it stopped on an error."
                    },
                    "last_run_at": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "When it last ran; null when it never has."
                    },
                    "next_run_at": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "When it runs next; null when paused, finished, or run on a call."
                    },
                    "run_count": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991,
                      "description": "How many times it has run."
                    },
                    "created_at": {
                      "type": "string",
                      "description": "When it was made, as an ISO 8601 date and time in UTC."
                    },
                    "updated_at": {
                      "type": "string",
                      "description": "When it last changed, as an ISO 8601 date and time in UTC."
                    }
                  },
                  "required": [
                    "id",
                    "object",
                    "user_id",
                    "conversation_id",
                    "name",
                    "ask",
                    "kind",
                    "schedule",
                    "trigger",
                    "trigger_url",
                    "enabled",
                    "status",
                    "last_run_at",
                    "next_run_at",
                    "run_count",
                    "created_at",
                    "updated_at"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "user_id": {
                    "description": "Whose Bash runs it: your id for the user. Absent: your company's own Bash.",
                    "examples": [
                      "traveller-42"
                    ],
                    "type": "string",
                    "pattern": "^[A-Za-z0-9][A-Za-z0-9._:@-]{0,127}$"
                  },
                  "ask": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 8000,
                    "description": "What Bash is asked on every run, as a person would ask it, up to 8,000 characters.",
                    "examples": [
                      "Check today's trips for delays and tell me what changed."
                    ]
                  },
                  "name": {
                    "description": "Its name, up to 200 characters. Absent: the start of `ask`.",
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 200
                  },
                  "every": {
                    "description": "When it runs, in plain words: `weekday at 08:00`, `mon, wed, fri at 18:30`, `30 minutes`, `month on the 1st at 09:00`. At most once every 15 minutes. Give one of `every`, `schedule` or `on`.",
                    "examples": [
                      "weekday at 08:00"
                    ],
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100
                  },
                  "timezone": {
                    "description": "The zone `every` is read in, an IANA name such as `Asia/Kolkata`. Absent: the user's own, then UTC.",
                    "examples": [
                      "Asia/Kolkata"
                    ],
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 64
                  },
                  "schedule": {
                    "description": "When it runs, as cron, instead of `every`.",
                    "type": "object",
                    "properties": {
                      "cron": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 120,
                        "description": "A cron expression of five fields: `0 7 * * *` runs at 7:00 every day.",
                        "examples": [
                          "0 7 * * 1-5"
                        ]
                      },
                      "timezone": {
                        "description": "The zone the cron is read in, an IANA name such as `Asia/Kolkata`. Absent: the user's own, then UTC.",
                        "examples": [
                          "Asia/Kolkata"
                        ],
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 64
                      }
                    },
                    "required": [
                      "cron"
                    ],
                    "additionalProperties": false
                  },
                  "on": {
                    "description": "`call`: it runs whenever your system posts to its `trigger_url`, instead of on a schedule.",
                    "type": "string",
                    "const": "call"
                  },
                  "filters": {
                    "description": "With `on: call`, the fields and values a payload must carry for the routine to run; any other payload is `filtered`.",
                    "examples": [
                      {
                        "event": "flight.delayed"
                      }
                    ],
                    "type": "object",
                    "propertyNames": {
                      "type": "string"
                    },
                    "additionalProperties": {}
                  },
                  "conversation_id": {
                    "description": "An existing conversation of this user that each run posts into. Absent: the routine gets its own.",
                    "type": "string",
                    "minLength": 1
                  },
                  "deployment": {
                    "description": "For the routine's own conversation, a deployment by its `dep_` id or name. Absent: the user's default, then the company's.",
                    "type": "string",
                    "minLength": 1
                  },
                  "enabled": {
                    "default": true,
                    "description": "false makes it paused: it keeps its schedule but does not run. Default true.",
                    "type": "boolean"
                  }
                },
                "required": [
                  "ask"
                ],
                "additionalProperties": false
              }
            }
          }
        }
      },
      "get": {
        "operationId": "getRoutines",
        "summary": "The routines of one user (user_id), or of the company's own Bash.",
        "tags": [
          "Routines"
        ],
        "x-vestra-line": "routines",
        "x-vestra-scope": "runtime",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "default": 20,
              "description": "How many items per page, 1 to 100. Default 20.",
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "description": "Where to go on from: the `next_cursor` of the page before, unchanged. Absent: the first page.",
              "type": "string"
            }
          },
          {
            "name": "user_id",
            "in": "query",
            "required": false,
            "schema": {
              "description": "Whose routines: your id for the user. Absent: your company's own Bash's.",
              "type": "string",
              "pattern": "^[A-Za-z0-9][A-Za-z0-9._:@-]{0,127}$",
              "examples": [
                "traveller-42"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "The routine's id.",
                            "examples": [
                              "rtn_8f2k"
                            ]
                          },
                          "object": {
                            "type": "string",
                            "const": "routine",
                            "description": "Always `routine`."
                          },
                          "user_id": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "Your id for the user whose Bash runs it; null for your company's own Bash."
                          },
                          "conversation_id": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "The conversation each run posts into, named or made when the routine was; null for a routine not made through the API."
                          },
                          "name": {
                            "type": "string",
                            "description": "Its name."
                          },
                          "ask": {
                            "type": "string",
                            "description": "What Bash is asked on every run."
                          },
                          "kind": {
                            "type": "string",
                            "enum": [
                              "schedule",
                              "trigger",
                              "app_event"
                            ],
                            "description": "`schedule`: it runs on its schedule. `trigger`: it runs when your system posts to `trigger_url`. `app_event`: an event in a connected app runs it."
                          },
                          "schedule": {
                            "anyOf": [
                              {
                                "type": "object",
                                "properties": {
                                  "every": {
                                    "anyOf": [
                                      {
                                        "type": "string"
                                      },
                                      {
                                        "type": "null"
                                      }
                                    ],
                                    "description": "The plain words it was given; null for a cron."
                                  },
                                  "cron": {
                                    "type": "string",
                                    "description": "The schedule as cron, worked out from `every` when it was given in words."
                                  },
                                  "timezone": {
                                    "type": "string",
                                    "description": "The zone it runs in, an IANA name."
                                  }
                                },
                                "required": [
                                  "every",
                                  "cron",
                                  "timezone"
                                ]
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "When it runs; null for one that runs on a call."
                          },
                          "trigger": {
                            "anyOf": [
                              {
                                "type": "object",
                                "properties": {
                                  "filters": {
                                    "anyOf": [
                                      {
                                        "type": "object",
                                        "propertyNames": {
                                          "type": "string"
                                        },
                                        "additionalProperties": {}
                                      },
                                      {
                                        "type": "null"
                                      }
                                    ],
                                    "description": "What a payload must carry for it to run; null: any payload."
                                  }
                                },
                                "required": [
                                  "filters"
                                ]
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "For one that runs on a call, what it listens for; null for one on a schedule."
                          },
                          "trigger_url": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "For one that runs on a call: POST here, with your key and any JSON object, to run it. Null otherwise."
                          },
                          "enabled": {
                            "type": "boolean",
                            "description": "false while it is paused."
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "active",
                              "completed",
                              "failed"
                            ],
                            "description": "`active`: it runs as it should. `completed`: it has finished and will not run again. `failed`: it stopped on an error."
                          },
                          "last_run_at": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "When it last ran; null when it never has."
                          },
                          "next_run_at": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "When it runs next; null when paused, finished, or run on a call."
                          },
                          "run_count": {
                            "type": "integer",
                            "minimum": -9007199254740991,
                            "maximum": 9007199254740991,
                            "description": "How many times it has run."
                          },
                          "created_at": {
                            "type": "string",
                            "description": "When it was made, as an ISO 8601 date and time in UTC."
                          },
                          "updated_at": {
                            "type": "string",
                            "description": "When it last changed, as an ISO 8601 date and time in UTC."
                          }
                        },
                        "required": [
                          "id",
                          "object",
                          "user_id",
                          "conversation_id",
                          "name",
                          "ask",
                          "kind",
                          "schedule",
                          "trigger",
                          "trigger_url",
                          "enabled",
                          "status",
                          "last_run_at",
                          "next_run_at",
                          "run_count",
                          "created_at",
                          "updated_at"
                        ]
                      },
                      "description": "The items on this page."
                    },
                    "next_cursor": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Send it as `cursor` for the next page; null on the last page."
                    }
                  },
                  "required": [
                    "data",
                    "next_cursor"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/routines/{routine_id}": {
      "get": {
        "operationId": "getRoutinesByRoutineId",
        "summary": "One routine.",
        "tags": [
          "Routines"
        ],
        "x-vestra-line": "routines",
        "x-vestra-scope": "runtime",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "routine_id",
            "in": "path",
            "required": true,
            "description": "The routine's id (`rtn_...`).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "The routine's id.",
                      "examples": [
                        "rtn_8f2k"
                      ]
                    },
                    "object": {
                      "type": "string",
                      "const": "routine",
                      "description": "Always `routine`."
                    },
                    "user_id": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Your id for the user whose Bash runs it; null for your company's own Bash."
                    },
                    "conversation_id": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The conversation each run posts into, named or made when the routine was; null for a routine not made through the API."
                    },
                    "name": {
                      "type": "string",
                      "description": "Its name."
                    },
                    "ask": {
                      "type": "string",
                      "description": "What Bash is asked on every run."
                    },
                    "kind": {
                      "type": "string",
                      "enum": [
                        "schedule",
                        "trigger",
                        "app_event"
                      ],
                      "description": "`schedule`: it runs on its schedule. `trigger`: it runs when your system posts to `trigger_url`. `app_event`: an event in a connected app runs it."
                    },
                    "schedule": {
                      "anyOf": [
                        {
                          "type": "object",
                          "properties": {
                            "every": {
                              "anyOf": [
                                {
                                  "type": "string"
                                },
                                {
                                  "type": "null"
                                }
                              ],
                              "description": "The plain words it was given; null for a cron."
                            },
                            "cron": {
                              "type": "string",
                              "description": "The schedule as cron, worked out from `every` when it was given in words."
                            },
                            "timezone": {
                              "type": "string",
                              "description": "The zone it runs in, an IANA name."
                            }
                          },
                          "required": [
                            "every",
                            "cron",
                            "timezone"
                          ]
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "When it runs; null for one that runs on a call."
                    },
                    "trigger": {
                      "anyOf": [
                        {
                          "type": "object",
                          "properties": {
                            "filters": {
                              "anyOf": [
                                {
                                  "type": "object",
                                  "propertyNames": {
                                    "type": "string"
                                  },
                                  "additionalProperties": {}
                                },
                                {
                                  "type": "null"
                                }
                              ],
                              "description": "What a payload must carry for it to run; null: any payload."
                            }
                          },
                          "required": [
                            "filters"
                          ]
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "For one that runs on a call, what it listens for; null for one on a schedule."
                    },
                    "trigger_url": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "For one that runs on a call: POST here, with your key and any JSON object, to run it. Null otherwise."
                    },
                    "enabled": {
                      "type": "boolean",
                      "description": "false while it is paused."
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "active",
                        "completed",
                        "failed"
                      ],
                      "description": "`active`: it runs as it should. `completed`: it has finished and will not run again. `failed`: it stopped on an error."
                    },
                    "last_run_at": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "When it last ran; null when it never has."
                    },
                    "next_run_at": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "When it runs next; null when paused, finished, or run on a call."
                    },
                    "run_count": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991,
                      "description": "How many times it has run."
                    },
                    "created_at": {
                      "type": "string",
                      "description": "When it was made, as an ISO 8601 date and time in UTC."
                    },
                    "updated_at": {
                      "type": "string",
                      "description": "When it last changed, as an ISO 8601 date and time in UTC."
                    }
                  },
                  "required": [
                    "id",
                    "object",
                    "user_id",
                    "conversation_id",
                    "name",
                    "ask",
                    "kind",
                    "schedule",
                    "trigger",
                    "trigger_url",
                    "enabled",
                    "status",
                    "last_run_at",
                    "next_run_at",
                    "run_count",
                    "created_at",
                    "updated_at"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "patchRoutinesByRoutineId",
        "summary": "Change what it asks, when it runs (every, schedule or timezone), its filters, or pause and resume it.",
        "tags": [
          "Routines"
        ],
        "x-vestra-line": "routines",
        "x-vestra-scope": "runtime",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "routine_id",
            "in": "path",
            "required": true,
            "description": "The routine's id (`rtn_...`).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "The routine's id.",
                      "examples": [
                        "rtn_8f2k"
                      ]
                    },
                    "object": {
                      "type": "string",
                      "const": "routine",
                      "description": "Always `routine`."
                    },
                    "user_id": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Your id for the user whose Bash runs it; null for your company's own Bash."
                    },
                    "conversation_id": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The conversation each run posts into, named or made when the routine was; null for a routine not made through the API."
                    },
                    "name": {
                      "type": "string",
                      "description": "Its name."
                    },
                    "ask": {
                      "type": "string",
                      "description": "What Bash is asked on every run."
                    },
                    "kind": {
                      "type": "string",
                      "enum": [
                        "schedule",
                        "trigger",
                        "app_event"
                      ],
                      "description": "`schedule`: it runs on its schedule. `trigger`: it runs when your system posts to `trigger_url`. `app_event`: an event in a connected app runs it."
                    },
                    "schedule": {
                      "anyOf": [
                        {
                          "type": "object",
                          "properties": {
                            "every": {
                              "anyOf": [
                                {
                                  "type": "string"
                                },
                                {
                                  "type": "null"
                                }
                              ],
                              "description": "The plain words it was given; null for a cron."
                            },
                            "cron": {
                              "type": "string",
                              "description": "The schedule as cron, worked out from `every` when it was given in words."
                            },
                            "timezone": {
                              "type": "string",
                              "description": "The zone it runs in, an IANA name."
                            }
                          },
                          "required": [
                            "every",
                            "cron",
                            "timezone"
                          ]
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "When it runs; null for one that runs on a call."
                    },
                    "trigger": {
                      "anyOf": [
                        {
                          "type": "object",
                          "properties": {
                            "filters": {
                              "anyOf": [
                                {
                                  "type": "object",
                                  "propertyNames": {
                                    "type": "string"
                                  },
                                  "additionalProperties": {}
                                },
                                {
                                  "type": "null"
                                }
                              ],
                              "description": "What a payload must carry for it to run; null: any payload."
                            }
                          },
                          "required": [
                            "filters"
                          ]
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "For one that runs on a call, what it listens for; null for one on a schedule."
                    },
                    "trigger_url": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "For one that runs on a call: POST here, with your key and any JSON object, to run it. Null otherwise."
                    },
                    "enabled": {
                      "type": "boolean",
                      "description": "false while it is paused."
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "active",
                        "completed",
                        "failed"
                      ],
                      "description": "`active`: it runs as it should. `completed`: it has finished and will not run again. `failed`: it stopped on an error."
                    },
                    "last_run_at": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "When it last ran; null when it never has."
                    },
                    "next_run_at": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "When it runs next; null when paused, finished, or run on a call."
                    },
                    "run_count": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991,
                      "description": "How many times it has run."
                    },
                    "created_at": {
                      "type": "string",
                      "description": "When it was made, as an ISO 8601 date and time in UTC."
                    },
                    "updated_at": {
                      "type": "string",
                      "description": "When it last changed, as an ISO 8601 date and time in UTC."
                    }
                  },
                  "required": [
                    "id",
                    "object",
                    "user_id",
                    "conversation_id",
                    "name",
                    "ask",
                    "kind",
                    "schedule",
                    "trigger",
                    "trigger_url",
                    "enabled",
                    "status",
                    "last_run_at",
                    "next_run_at",
                    "run_count",
                    "created_at",
                    "updated_at"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "description": "A new name, up to 200 characters.",
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 200
                  },
                  "ask": {
                    "description": "What Bash is asked on every run from now on, up to 8,000 characters.",
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 8000
                  },
                  "every": {
                    "description": "A new schedule. When it runs, in plain words: `weekday at 08:00`, `mon, wed, fri at 18:30`, `30 minutes`, `month on the 1st at 09:00`. At most once every 15 minutes.",
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100
                  },
                  "timezone": {
                    "description": "A new zone, an IANA name, for the schedule it already has or for new plain words.",
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 64
                  },
                  "schedule": {
                    "description": "A new schedule as cron, instead of `every`.",
                    "type": "object",
                    "properties": {
                      "cron": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 120,
                        "description": "A cron expression of five fields: `0 7 * * *` runs at 7:00 every day.",
                        "examples": [
                          "0 7 * * 1-5"
                        ]
                      },
                      "timezone": {
                        "description": "The zone the cron is read in, an IANA name such as `Asia/Kolkata`. Absent: the user's own, then UTC.",
                        "examples": [
                          "Asia/Kolkata"
                        ],
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 64
                      }
                    },
                    "required": [
                      "cron"
                    ],
                    "additionalProperties": false
                  },
                  "filters": {
                    "description": "New filters, for a routine that runs on a call.",
                    "type": "object",
                    "propertyNames": {
                      "type": "string"
                    },
                    "additionalProperties": {}
                  },
                  "enabled": {
                    "description": "false pauses it; true resumes it.",
                    "type": "boolean"
                  }
                },
                "additionalProperties": false
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteRoutinesByRoutineId",
        "summary": "Delete it.",
        "tags": [
          "Routines"
        ],
        "x-vestra-line": "routines",
        "x-vestra-scope": "runtime",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "routine_id",
            "in": "path",
            "required": true,
            "description": "The routine's id (`rtn_...`).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "The deleted routine's id."
                    },
                    "object": {
                      "type": "string",
                      "const": "routine",
                      "description": "Always `routine`."
                    },
                    "deleted": {
                      "type": "boolean",
                      "const": true,
                      "description": "Always true: it is gone and never runs again."
                    }
                  },
                  "required": [
                    "id",
                    "object",
                    "deleted"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/routines/{routine_id}/run": {
      "post": {
        "operationId": "postRoutinesByRoutineIdRun",
        "summary": "Run it now.",
        "tags": [
          "Routines"
        ],
        "x-vestra-line": "routines",
        "x-vestra-scope": "runtime",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "routine_id",
            "in": "path",
            "required": true,
            "description": "The routine's id (`rtn_...`).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 255
            },
            "description": "Send the same key to retry this call safely for 24 hours."
          }
        ],
        "responses": {
          "202": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "type": "string",
                      "const": "routine_fire",
                      "description": "Always `routine_fire`."
                    },
                    "routine_id": {
                      "type": "string",
                      "description": "The routine it runs."
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "queued",
                        "duplicate",
                        "filtered"
                      ],
                      "description": "`queued`: it runs now. `duplicate`: the same run was already asked for, so it runs once. `filtered`: the payload did not match its `filters`, so it does not run."
                    }
                  },
                  "required": [
                    "object",
                    "routine_id",
                    "status"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/routines/{routine_id}/trigger": {
      "post": {
        "operationId": "postRoutinesByRoutineIdTrigger",
        "summary": "Fire it with a payload from your system: a train delayed, a refund posted.",
        "tags": [
          "Routines"
        ],
        "x-vestra-line": "routines",
        "x-vestra-scope": "runtime",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "routine_id",
            "in": "path",
            "required": true,
            "description": "The routine's id (`rtn_...`).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 255
            },
            "description": "Send the same key to retry this call safely for 24 hours."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "type": "string",
                      "const": "routine_fire",
                      "description": "Always `routine_fire`."
                    },
                    "routine_id": {
                      "type": "string",
                      "description": "The routine it runs."
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "queued",
                        "duplicate",
                        "filtered"
                      ],
                      "description": "`queued`: it runs now. `duplicate`: the same run was already asked for, so it runs once. `filtered`: the payload did not match its `filters`, so it does not run."
                    }
                  },
                  "required": [
                    "object",
                    "routine_id",
                    "status"
                  ]
                }
              }
            }
          },
          "202": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "type": "string",
                      "const": "routine_fire",
                      "description": "Always `routine_fire`."
                    },
                    "routine_id": {
                      "type": "string",
                      "description": "The routine it runs."
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "queued",
                        "duplicate",
                        "filtered"
                      ],
                      "description": "`queued`: it runs now. `duplicate`: the same run was already asked for, so it runs once. `filtered`: the payload did not match its `filters`, so it does not run."
                    }
                  },
                  "required": [
                    "object",
                    "routine_id",
                    "status"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "propertyNames": {
                  "type": "string"
                },
                "additionalProperties": {}
              }
            }
          }
        }
      }
    },
    "/v1/routines/{routine_id}/runs": {
      "get": {
        "operationId": "getRoutinesByRoutineIdRuns",
        "summary": "Past runs and the tasks they started.",
        "tags": [
          "Routines"
        ],
        "x-vestra-line": "routines",
        "x-vestra-scope": "runtime",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "routine_id",
            "in": "path",
            "required": true,
            "description": "The routine's id (`rtn_...`).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "default": 20,
              "description": "How many items per page, 1 to 100. Default 20.",
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "description": "Where to go on from: the `next_cursor` of the page before, unchanged. Absent: the first page.",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "The run's id."
                          },
                          "object": {
                            "type": "string",
                            "const": "routine_run",
                            "description": "Always `routine_run`."
                          },
                          "routine_id": {
                            "type": "string",
                            "description": "The routine it is a run of."
                          },
                          "conversation_id": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "The conversation the run's message landed in; null when it never got that far."
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "pending",
                              "running",
                              "completed",
                              "failed",
                              "skipped"
                            ],
                            "description": "`pending` or `running` while it goes. `completed`: Bash took the ask (the work it started is in `task_ids`). `failed`: it could not post the ask. `skipped`: it did not run, as `error` says."
                          },
                          "trigger_payload": {
                            "anyOf": [
                              {
                                "type": "object",
                                "propertyNames": {
                                  "type": "string"
                                },
                                "additionalProperties": {}
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "The payload your system sent, for a run on a call; null for a scheduled run."
                          },
                          "task_ids": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            },
                            "description": "The pieces of work the run started."
                          },
                          "error": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "Why it failed or was skipped; null otherwise."
                          },
                          "started_at": {
                            "type": "string",
                            "description": "When it began, as an ISO 8601 date and time in UTC."
                          },
                          "completed_at": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "When it ended; null while it goes."
                          }
                        },
                        "required": [
                          "id",
                          "object",
                          "routine_id",
                          "conversation_id",
                          "status",
                          "trigger_payload",
                          "task_ids",
                          "error",
                          "started_at",
                          "completed_at"
                        ]
                      },
                      "description": "The items on this page."
                    },
                    "next_cursor": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Send it as `cursor` for the next page; null on the last page."
                    }
                  },
                  "required": [
                    "data",
                    "next_cursor"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/batches": {
      "post": {
        "operationId": "postBatches",
        "summary": "Start a batch: a deployment, a list of items (user_id optional, message, context, metadata) and a concurrency. Each item is one conversation message with hand_off: always.",
        "tags": [
          "Batches"
        ],
        "x-vestra-line": "ask",
        "x-vestra-scope": "runtime",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 255
            },
            "description": "Send the same key to retry this call safely for 24 hours."
          }
        ],
        "responses": {
          "201": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "The batch (bat_...).",
                      "examples": [
                        "bat_7xk"
                      ]
                    },
                    "object": {
                      "type": "string",
                      "const": "batch",
                      "description": "Always batch."
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "running",
                        "cancelled",
                        "completed"
                      ],
                      "description": "running: items are still starting or running. cancelled: you cancelled it, so no new item starts. completed: every item has finished."
                    },
                    "deployment_id": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The deployment that answers its items (dep_...); null when none applies."
                    },
                    "concurrency": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991,
                      "description": "How many items run at once."
                    },
                    "item_count": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991,
                      "description": "How many items it has."
                    },
                    "counts": {
                      "type": "object",
                      "properties": {
                        "queued": {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991,
                          "description": "Items not started yet."
                        },
                        "running": {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991,
                          "description": "Items running now."
                        },
                        "succeeded": {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991,
                          "description": "Items that finished well."
                        },
                        "failed": {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991,
                          "description": "Items that failed."
                        },
                        "cancelled": {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991,
                          "description": "Items a cancel kept from starting."
                        }
                      },
                      "required": [
                        "queued",
                        "running",
                        "succeeded",
                        "failed",
                        "cancelled"
                      ],
                      "description": "Its items, by status."
                    },
                    "spend_usd": {
                      "type": "number",
                      "description": "What it has cost so far, in billed US dollars: every item's conversation and all its work.",
                      "examples": [
                        0.061
                      ]
                    },
                    "metadata": {
                      "type": "object",
                      "propertyNames": {
                        "type": "string"
                      },
                      "additionalProperties": {
                        "type": "string"
                      },
                      "description": "Your labels, as you sent them; empty when you sent none."
                    },
                    "created_at": {
                      "type": "string",
                      "description": "When it was made, as an ISO 8601 time."
                    },
                    "completed_at": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "When it stopped running, completed or cancelled, as an ISO 8601 time; null while running."
                    }
                  },
                  "required": [
                    "id",
                    "object",
                    "status",
                    "deployment_id",
                    "concurrency",
                    "item_count",
                    "counts",
                    "spend_usd",
                    "metadata",
                    "created_at",
                    "completed_at"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "deployment": {
                    "description": "Which deployment answers every item: its id or name, never a pinned version. Absent: your company's default deployment.",
                    "type": "string",
                    "minLength": 1
                  },
                  "items": {
                    "minItems": 1,
                    "maxItems": 5000,
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "user_id": {
                          "description": "Your id for the user this item is for. Absent: your company's own Bash.",
                          "type": "string",
                          "pattern": "^[A-Za-z0-9][A-Za-z0-9._:@-]{0,127}$",
                          "examples": [
                            "traveller-42"
                          ]
                        },
                        "message": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 32000,
                          "description": "What Bash is asked, in at most 32,000 characters. It goes straight to work.",
                          "examples": [
                            "Is your flight hit by the storm?"
                          ]
                        },
                        "context": {
                          "description": "Facts for this item only, as JSON: Bash reads them as data, never as instructions.",
                          "type": "object",
                          "propertyNames": {
                            "type": "string"
                          },
                          "additionalProperties": {}
                        },
                        "metadata": {
                          "type": "object",
                          "propertyNames": {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 64
                          },
                          "additionalProperties": {
                            "type": "string",
                            "maxLength": 512
                          },
                          "description": "Your own labels, given back as you sent them: at most 32 keys of 1 to 64 characters, each value a string of at most 512. Bash never reads them.",
                          "examples": [
                            {
                              "order_id": "ORD-1042",
                              "channel": "app"
                            }
                          ]
                        }
                      },
                      "required": [
                        "message"
                      ],
                      "additionalProperties": false
                    },
                    "description": "The jobs: 1 to 5,000, each one conversation."
                  },
                  "concurrency": {
                    "default": 10,
                    "description": "How many items run at once, 1 to 100. Default: 10. Items with no user share your company's own Bash, 5 at a time at most.",
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 100
                  },
                  "metadata": {
                    "type": "object",
                    "propertyNames": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 64
                    },
                    "additionalProperties": {
                      "type": "string",
                      "maxLength": 512
                    },
                    "description": "Your own labels, given back as you sent them: at most 32 keys of 1 to 64 characters, each value a string of at most 512. Bash never reads them.",
                    "examples": [
                      {
                        "order_id": "ORD-1042",
                        "channel": "app"
                      }
                    ]
                  }
                },
                "required": [
                  "items"
                ],
                "additionalProperties": false
              }
            }
          }
        }
      }
    },
    "/v1/batches/{batch_id}": {
      "get": {
        "operationId": "getBatchesByBatchId",
        "summary": "Progress: counts by status, spend so far.",
        "tags": [
          "Batches"
        ],
        "x-vestra-line": "ask",
        "x-vestra-scope": "runtime",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "batch_id",
            "in": "path",
            "required": true,
            "description": "The batch's id (`bat_...`).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "The batch (bat_...).",
                      "examples": [
                        "bat_7xk"
                      ]
                    },
                    "object": {
                      "type": "string",
                      "const": "batch",
                      "description": "Always batch."
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "running",
                        "cancelled",
                        "completed"
                      ],
                      "description": "running: items are still starting or running. cancelled: you cancelled it, so no new item starts. completed: every item has finished."
                    },
                    "deployment_id": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The deployment that answers its items (dep_...); null when none applies."
                    },
                    "concurrency": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991,
                      "description": "How many items run at once."
                    },
                    "item_count": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991,
                      "description": "How many items it has."
                    },
                    "counts": {
                      "type": "object",
                      "properties": {
                        "queued": {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991,
                          "description": "Items not started yet."
                        },
                        "running": {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991,
                          "description": "Items running now."
                        },
                        "succeeded": {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991,
                          "description": "Items that finished well."
                        },
                        "failed": {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991,
                          "description": "Items that failed."
                        },
                        "cancelled": {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991,
                          "description": "Items a cancel kept from starting."
                        }
                      },
                      "required": [
                        "queued",
                        "running",
                        "succeeded",
                        "failed",
                        "cancelled"
                      ],
                      "description": "Its items, by status."
                    },
                    "spend_usd": {
                      "type": "number",
                      "description": "What it has cost so far, in billed US dollars: every item's conversation and all its work.",
                      "examples": [
                        0.061
                      ]
                    },
                    "metadata": {
                      "type": "object",
                      "propertyNames": {
                        "type": "string"
                      },
                      "additionalProperties": {
                        "type": "string"
                      },
                      "description": "Your labels, as you sent them; empty when you sent none."
                    },
                    "created_at": {
                      "type": "string",
                      "description": "When it was made, as an ISO 8601 time."
                    },
                    "completed_at": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "When it stopped running, completed or cancelled, as an ISO 8601 time; null while running."
                    }
                  },
                  "required": [
                    "id",
                    "object",
                    "status",
                    "deployment_id",
                    "concurrency",
                    "item_count",
                    "counts",
                    "spend_usd",
                    "metadata",
                    "created_at",
                    "completed_at"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/batches/{batch_id}/items": {
      "get": {
        "operationId": "getBatchesByBatchIdItems",
        "summary": "Each item with its task id and result.",
        "tags": [
          "Batches"
        ],
        "x-vestra-line": "ask",
        "x-vestra-scope": "runtime",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "batch_id",
            "in": "path",
            "required": true,
            "description": "The batch's id (`bat_...`).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "default": 20,
              "description": "How many items per page, 1 to 100. Default 20.",
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "description": "Where to go on from: the `next_cursor` of the page before, unchanged. Absent: the first page.",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "object": {
                            "type": "string",
                            "const": "batch.item",
                            "description": "Always batch.item."
                          },
                          "index": {
                            "type": "integer",
                            "minimum": -9007199254740991,
                            "maximum": 9007199254740991,
                            "description": "Where it was in the items you sent, from 0."
                          },
                          "user_id": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "Your id for its user; null on your company's own Bash."
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "queued",
                              "running",
                              "succeeded",
                              "failed",
                              "cancelled"
                            ],
                            "description": "queued: not started yet. running: its conversation is working. succeeded or failed: it has finished. cancelled: the batch was cancelled before it started."
                          },
                          "conversation_id": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "The conversation it runs in (conv_...); null until it starts."
                          },
                          "task_id": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "The work it started (task_...); null until it starts work."
                          },
                          "result": {
                            "anyOf": [
                              {
                                "type": "object",
                                "properties": {
                                  "reply": {
                                    "anyOf": [
                                      {
                                        "type": "string"
                                      },
                                      {
                                        "type": "null"
                                      }
                                    ],
                                    "description": "What Bash said when it took the item: an item goes straight to work, so this is the one line Started work on it. The work's answer is text."
                                  },
                                  "text": {
                                    "anyOf": [
                                      {
                                        "type": "string"
                                      },
                                      {
                                        "type": "null"
                                      }
                                    ],
                                    "description": "The work's answer: its final reply, the words of its last step that said anything. Null when the item did not go to work (its reply is the answer then) or the work ended with no final reply.",
                                    "examples": [
                                      "Your flight 6E 2134 is on time."
                                    ]
                                  },
                                  "data": {
                                    "anyOf": [
                                      {},
                                      {
                                        "type": "null"
                                      }
                                    ],
                                    "description": "Data the work returned for an output_schema; null when it returned none."
                                  },
                                  "outcome": {
                                    "anyOf": [
                                      {
                                        "type": "object",
                                        "properties": {
                                          "met": {
                                            "type": "boolean",
                                            "description": "Whether the result met the success criteria."
                                          },
                                          "reason": {
                                            "type": "string",
                                            "description": "Why, in a sentence."
                                          }
                                        },
                                        "required": [
                                          "met",
                                          "reason"
                                        ]
                                      },
                                      {
                                        "type": "null"
                                      }
                                    ],
                                    "description": "Whether it met its success criteria; null when there were none."
                                  }
                                },
                                "required": [
                                  "reply",
                                  "text",
                                  "data",
                                  "outcome"
                                ]
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "What it came to, once it succeeded; null before, and when it failed."
                          },
                          "error": {
                            "anyOf": [
                              {
                                "type": "object",
                                "properties": {
                                  "code": {
                                    "type": "string",
                                    "description": "A stable code to branch on."
                                  },
                                  "message": {
                                    "type": "string",
                                    "description": "What went wrong, in plain words."
                                  }
                                },
                                "required": [
                                  "code",
                                  "message"
                                ]
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "Why it failed; null unless it did."
                          },
                          "metadata": {
                            "type": "object",
                            "propertyNames": {
                              "type": "string"
                            },
                            "additionalProperties": {
                              "type": "string"
                            },
                            "description": "Your labels for this item, as you sent them."
                          },
                          "created_at": {
                            "type": "string",
                            "description": "When the batch was made, as an ISO 8601 time."
                          },
                          "finished_at": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "When it finished, as an ISO 8601 time; null until then."
                          }
                        },
                        "required": [
                          "object",
                          "index",
                          "user_id",
                          "status",
                          "conversation_id",
                          "task_id",
                          "result",
                          "error",
                          "metadata",
                          "created_at",
                          "finished_at"
                        ]
                      },
                      "description": "The items on this page."
                    },
                    "next_cursor": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Send it as `cursor` for the next page; null on the last page."
                    }
                  },
                  "required": [
                    "data",
                    "next_cursor"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/batches/{batch_id}/cancel": {
      "post": {
        "operationId": "postBatchesByBatchIdCancel",
        "summary": "Stop starting new items; running ones finish.",
        "tags": [
          "Batches"
        ],
        "x-vestra-line": "ask",
        "x-vestra-scope": "runtime",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "batch_id",
            "in": "path",
            "required": true,
            "description": "The batch's id (`bat_...`).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 255
            },
            "description": "Send the same key to retry this call safely for 24 hours."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "The batch (bat_...).",
                      "examples": [
                        "bat_7xk"
                      ]
                    },
                    "object": {
                      "type": "string",
                      "const": "batch",
                      "description": "Always batch."
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "running",
                        "cancelled",
                        "completed"
                      ],
                      "description": "running: items are still starting or running. cancelled: you cancelled it, so no new item starts. completed: every item has finished."
                    },
                    "deployment_id": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The deployment that answers its items (dep_...); null when none applies."
                    },
                    "concurrency": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991,
                      "description": "How many items run at once."
                    },
                    "item_count": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991,
                      "description": "How many items it has."
                    },
                    "counts": {
                      "type": "object",
                      "properties": {
                        "queued": {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991,
                          "description": "Items not started yet."
                        },
                        "running": {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991,
                          "description": "Items running now."
                        },
                        "succeeded": {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991,
                          "description": "Items that finished well."
                        },
                        "failed": {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991,
                          "description": "Items that failed."
                        },
                        "cancelled": {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991,
                          "description": "Items a cancel kept from starting."
                        }
                      },
                      "required": [
                        "queued",
                        "running",
                        "succeeded",
                        "failed",
                        "cancelled"
                      ],
                      "description": "Its items, by status."
                    },
                    "spend_usd": {
                      "type": "number",
                      "description": "What it has cost so far, in billed US dollars: every item's conversation and all its work.",
                      "examples": [
                        0.061
                      ]
                    },
                    "metadata": {
                      "type": "object",
                      "propertyNames": {
                        "type": "string"
                      },
                      "additionalProperties": {
                        "type": "string"
                      },
                      "description": "Your labels, as you sent them; empty when you sent none."
                    },
                    "created_at": {
                      "type": "string",
                      "description": "When it was made, as an ISO 8601 time."
                    },
                    "completed_at": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "When it stopped running, completed or cancelled, as an ISO 8601 time; null while running."
                    }
                  },
                  "required": [
                    "id",
                    "object",
                    "status",
                    "deployment_id",
                    "concurrency",
                    "item_count",
                    "counts",
                    "spend_usd",
                    "metadata",
                    "created_at",
                    "completed_at"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/webhooks": {
      "post": {
        "operationId": "postWebhooks",
        "summary": "Register a URL and the events it wants. The signing secret is shown once.",
        "tags": [
          "Webhooks and events"
        ],
        "x-vestra-line": "events",
        "x-vestra-scope": "setup",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [],
        "responses": {
          "201": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "The endpoint (whk_...).",
                      "examples": [
                        "whk_2bq"
                      ]
                    },
                    "object": {
                      "type": "string",
                      "const": "webhook_endpoint",
                      "description": "Always webhook_endpoint."
                    },
                    "url": {
                      "type": "string",
                      "description": "Where the events go."
                    },
                    "events": {
                      "type": "array",
                      "items": {
                        "anyOf": [
                          {
                            "type": "string",
                            "enum": [
                              "message.completed",
                              "task.started",
                              "task.completed",
                              "task.failed",
                              "task.stopped",
                              "interaction.created",
                              "interaction.resolved",
                              "interaction.expired",
                              "session.started",
                              "session.ended",
                              "file.created",
                              "routine.fired",
                              "usage.threshold_reached",
                              "usage.cap_reached",
                              "conversation.status",
                              "user.created",
                              "user.deleted",
                              "connection.completed",
                              "connection.failed",
                              "connection.removed",
                              "memory.observed",
                              "batch.completed",
                              "deployment.version_created",
                              "deployment.promoted",
                              "deployment.rolled_back",
                              "test_run.completed",
                              "key.created",
                              "key.revoked"
                            ],
                            "description": "An event a webhook carries: every event of the catalog but the six that ride only the stream (message.delta, task.progress, usage.updated, screen.control, error and ping).",
                            "examples": [
                              "task.completed"
                            ]
                          },
                          {
                            "type": "string",
                            "const": "*"
                          }
                        ],
                        "description": "An event the endpoint wants, by its type, or * for every event a webhook carries.",
                        "examples": [
                          "task.completed"
                        ]
                      },
                      "description": "The events it wants."
                    },
                    "description": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Your note; null when you gave none."
                    },
                    "active": {
                      "type": "boolean",
                      "description": "Whether events are sent to it."
                    },
                    "mode": {
                      "type": "string",
                      "enum": [
                        "live",
                        "test"
                      ],
                      "description": "The mode it hears: test or live, the mode of the key that made it. A test endpoint never hears a live event."
                    },
                    "deployment_id": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Only this deployment's events reach it (dep_...), plus your account's, such as keys, users and usage alerts. Set when a deployment's vestra.yaml declared the endpoint. Null: every event its types allow."
                    },
                    "managed_by": {
                      "anyOf": [
                        {
                          "type": "string",
                          "const": "file"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "file: declared in that deployment's vestra.yaml, so deploying the file changes it; null: you made it."
                    },
                    "created_at": {
                      "type": "string",
                      "description": "When it was made, as an ISO 8601 time."
                    },
                    "updated_at": {
                      "type": "string",
                      "description": "When it last changed, as an ISO 8601 time."
                    },
                    "secret": {
                      "type": "string",
                      "description": "The signing secret, shown this once: check every delivery against it (the Vestra-Signature header). Keep it on your server.",
                      "examples": [
                        "whsec_..."
                      ]
                    }
                  },
                  "required": [
                    "id",
                    "object",
                    "url",
                    "events",
                    "description",
                    "active",
                    "mode",
                    "deployment_id",
                    "managed_by",
                    "created_at",
                    "updated_at",
                    "secret"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "url": {
                    "type": "string",
                    "maxLength": 2048,
                    "format": "uri",
                    "description": "Where to send the events: a public https URL, at most 2,048 characters. Private, local and internal addresses are refused.",
                    "examples": [
                      "https://api.example.com/vestra"
                    ]
                  },
                  "events": {
                    "minItems": 1,
                    "maxItems": 40,
                    "type": "array",
                    "items": {
                      "anyOf": [
                        {
                          "type": "string",
                          "enum": [
                            "message.completed",
                            "task.started",
                            "task.completed",
                            "task.failed",
                            "task.stopped",
                            "interaction.created",
                            "interaction.resolved",
                            "interaction.expired",
                            "session.started",
                            "session.ended",
                            "file.created",
                            "routine.fired",
                            "usage.threshold_reached",
                            "usage.cap_reached",
                            "conversation.status",
                            "user.created",
                            "user.deleted",
                            "connection.completed",
                            "connection.failed",
                            "connection.removed",
                            "memory.observed",
                            "batch.completed",
                            "deployment.version_created",
                            "deployment.promoted",
                            "deployment.rolled_back",
                            "test_run.completed",
                            "key.created",
                            "key.revoked"
                          ],
                          "description": "An event a webhook carries: every event of the catalog but the six that ride only the stream (message.delta, task.progress, usage.updated, screen.control, error and ping).",
                          "examples": [
                            "task.completed"
                          ]
                        },
                        {
                          "type": "string",
                          "const": "*"
                        }
                      ],
                      "description": "An event the endpoint wants, by its type, or * for every event a webhook carries.",
                      "examples": [
                        "task.completed"
                      ]
                    },
                    "description": "The events it wants: 1 to 40 types, or * for all."
                  },
                  "description": {
                    "description": "A note for you, in at most 500 characters.",
                    "type": "string",
                    "maxLength": 500
                  },
                  "active": {
                    "default": true,
                    "description": "Whether to send to it. Default: true.",
                    "type": "boolean"
                  }
                },
                "required": [
                  "url",
                  "events"
                ]
              }
            }
          }
        }
      },
      "get": {
        "operationId": "getWebhooks",
        "summary": "Your endpoints.",
        "tags": [
          "Webhooks and events"
        ],
        "x-vestra-line": "events",
        "x-vestra-scope": "setup",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "default": 20,
              "description": "How many items per page, 1 to 100. Default 20.",
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "description": "Where to go on from: the `next_cursor` of the page before, unchanged. Absent: the first page.",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "The endpoint (whk_...).",
                            "examples": [
                              "whk_2bq"
                            ]
                          },
                          "object": {
                            "type": "string",
                            "const": "webhook_endpoint",
                            "description": "Always webhook_endpoint."
                          },
                          "url": {
                            "type": "string",
                            "description": "Where the events go."
                          },
                          "events": {
                            "type": "array",
                            "items": {
                              "anyOf": [
                                {
                                  "type": "string",
                                  "enum": [
                                    "message.completed",
                                    "task.started",
                                    "task.completed",
                                    "task.failed",
                                    "task.stopped",
                                    "interaction.created",
                                    "interaction.resolved",
                                    "interaction.expired",
                                    "session.started",
                                    "session.ended",
                                    "file.created",
                                    "routine.fired",
                                    "usage.threshold_reached",
                                    "usage.cap_reached",
                                    "conversation.status",
                                    "user.created",
                                    "user.deleted",
                                    "connection.completed",
                                    "connection.failed",
                                    "connection.removed",
                                    "memory.observed",
                                    "batch.completed",
                                    "deployment.version_created",
                                    "deployment.promoted",
                                    "deployment.rolled_back",
                                    "test_run.completed",
                                    "key.created",
                                    "key.revoked"
                                  ],
                                  "description": "An event a webhook carries: every event of the catalog but the six that ride only the stream (message.delta, task.progress, usage.updated, screen.control, error and ping).",
                                  "examples": [
                                    "task.completed"
                                  ]
                                },
                                {
                                  "type": "string",
                                  "const": "*"
                                }
                              ],
                              "description": "An event the endpoint wants, by its type, or * for every event a webhook carries.",
                              "examples": [
                                "task.completed"
                              ]
                            },
                            "description": "The events it wants."
                          },
                          "description": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "Your note; null when you gave none."
                          },
                          "active": {
                            "type": "boolean",
                            "description": "Whether events are sent to it."
                          },
                          "mode": {
                            "type": "string",
                            "enum": [
                              "live",
                              "test"
                            ],
                            "description": "The mode it hears: test or live, the mode of the key that made it. A test endpoint never hears a live event."
                          },
                          "deployment_id": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "Only this deployment's events reach it (dep_...), plus your account's, such as keys, users and usage alerts. Set when a deployment's vestra.yaml declared the endpoint. Null: every event its types allow."
                          },
                          "managed_by": {
                            "anyOf": [
                              {
                                "type": "string",
                                "const": "file"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "file: declared in that deployment's vestra.yaml, so deploying the file changes it; null: you made it."
                          },
                          "created_at": {
                            "type": "string",
                            "description": "When it was made, as an ISO 8601 time."
                          },
                          "updated_at": {
                            "type": "string",
                            "description": "When it last changed, as an ISO 8601 time."
                          }
                        },
                        "required": [
                          "id",
                          "object",
                          "url",
                          "events",
                          "description",
                          "active",
                          "mode",
                          "deployment_id",
                          "managed_by",
                          "created_at",
                          "updated_at"
                        ]
                      },
                      "description": "The items on this page."
                    },
                    "next_cursor": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Send it as `cursor` for the next page; null on the last page."
                    }
                  },
                  "required": [
                    "data",
                    "next_cursor"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/webhooks/{endpoint_id}": {
      "get": {
        "operationId": "getWebhooksByEndpointId",
        "summary": "One endpoint.",
        "tags": [
          "Webhooks and events"
        ],
        "x-vestra-line": "events",
        "x-vestra-scope": "setup",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "endpoint_id",
            "in": "path",
            "required": true,
            "description": "The webhook endpoint's id (`whk_...`).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "The endpoint (whk_...).",
                      "examples": [
                        "whk_2bq"
                      ]
                    },
                    "object": {
                      "type": "string",
                      "const": "webhook_endpoint",
                      "description": "Always webhook_endpoint."
                    },
                    "url": {
                      "type": "string",
                      "description": "Where the events go."
                    },
                    "events": {
                      "type": "array",
                      "items": {
                        "anyOf": [
                          {
                            "type": "string",
                            "enum": [
                              "message.completed",
                              "task.started",
                              "task.completed",
                              "task.failed",
                              "task.stopped",
                              "interaction.created",
                              "interaction.resolved",
                              "interaction.expired",
                              "session.started",
                              "session.ended",
                              "file.created",
                              "routine.fired",
                              "usage.threshold_reached",
                              "usage.cap_reached",
                              "conversation.status",
                              "user.created",
                              "user.deleted",
                              "connection.completed",
                              "connection.failed",
                              "connection.removed",
                              "memory.observed",
                              "batch.completed",
                              "deployment.version_created",
                              "deployment.promoted",
                              "deployment.rolled_back",
                              "test_run.completed",
                              "key.created",
                              "key.revoked"
                            ],
                            "description": "An event a webhook carries: every event of the catalog but the six that ride only the stream (message.delta, task.progress, usage.updated, screen.control, error and ping).",
                            "examples": [
                              "task.completed"
                            ]
                          },
                          {
                            "type": "string",
                            "const": "*"
                          }
                        ],
                        "description": "An event the endpoint wants, by its type, or * for every event a webhook carries.",
                        "examples": [
                          "task.completed"
                        ]
                      },
                      "description": "The events it wants."
                    },
                    "description": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Your note; null when you gave none."
                    },
                    "active": {
                      "type": "boolean",
                      "description": "Whether events are sent to it."
                    },
                    "mode": {
                      "type": "string",
                      "enum": [
                        "live",
                        "test"
                      ],
                      "description": "The mode it hears: test or live, the mode of the key that made it. A test endpoint never hears a live event."
                    },
                    "deployment_id": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Only this deployment's events reach it (dep_...), plus your account's, such as keys, users and usage alerts. Set when a deployment's vestra.yaml declared the endpoint. Null: every event its types allow."
                    },
                    "managed_by": {
                      "anyOf": [
                        {
                          "type": "string",
                          "const": "file"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "file: declared in that deployment's vestra.yaml, so deploying the file changes it; null: you made it."
                    },
                    "created_at": {
                      "type": "string",
                      "description": "When it was made, as an ISO 8601 time."
                    },
                    "updated_at": {
                      "type": "string",
                      "description": "When it last changed, as an ISO 8601 time."
                    }
                  },
                  "required": [
                    "id",
                    "object",
                    "url",
                    "events",
                    "description",
                    "active",
                    "mode",
                    "deployment_id",
                    "managed_by",
                    "created_at",
                    "updated_at"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "patchWebhooksByEndpointId",
        "summary": "Change URL or events, switch it on or off.",
        "tags": [
          "Webhooks and events"
        ],
        "x-vestra-line": "events",
        "x-vestra-scope": "setup",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "endpoint_id",
            "in": "path",
            "required": true,
            "description": "The webhook endpoint's id (`whk_...`).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "The endpoint (whk_...).",
                      "examples": [
                        "whk_2bq"
                      ]
                    },
                    "object": {
                      "type": "string",
                      "const": "webhook_endpoint",
                      "description": "Always webhook_endpoint."
                    },
                    "url": {
                      "type": "string",
                      "description": "Where the events go."
                    },
                    "events": {
                      "type": "array",
                      "items": {
                        "anyOf": [
                          {
                            "type": "string",
                            "enum": [
                              "message.completed",
                              "task.started",
                              "task.completed",
                              "task.failed",
                              "task.stopped",
                              "interaction.created",
                              "interaction.resolved",
                              "interaction.expired",
                              "session.started",
                              "session.ended",
                              "file.created",
                              "routine.fired",
                              "usage.threshold_reached",
                              "usage.cap_reached",
                              "conversation.status",
                              "user.created",
                              "user.deleted",
                              "connection.completed",
                              "connection.failed",
                              "connection.removed",
                              "memory.observed",
                              "batch.completed",
                              "deployment.version_created",
                              "deployment.promoted",
                              "deployment.rolled_back",
                              "test_run.completed",
                              "key.created",
                              "key.revoked"
                            ],
                            "description": "An event a webhook carries: every event of the catalog but the six that ride only the stream (message.delta, task.progress, usage.updated, screen.control, error and ping).",
                            "examples": [
                              "task.completed"
                            ]
                          },
                          {
                            "type": "string",
                            "const": "*"
                          }
                        ],
                        "description": "An event the endpoint wants, by its type, or * for every event a webhook carries.",
                        "examples": [
                          "task.completed"
                        ]
                      },
                      "description": "The events it wants."
                    },
                    "description": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Your note; null when you gave none."
                    },
                    "active": {
                      "type": "boolean",
                      "description": "Whether events are sent to it."
                    },
                    "mode": {
                      "type": "string",
                      "enum": [
                        "live",
                        "test"
                      ],
                      "description": "The mode it hears: test or live, the mode of the key that made it. A test endpoint never hears a live event."
                    },
                    "deployment_id": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Only this deployment's events reach it (dep_...), plus your account's, such as keys, users and usage alerts. Set when a deployment's vestra.yaml declared the endpoint. Null: every event its types allow."
                    },
                    "managed_by": {
                      "anyOf": [
                        {
                          "type": "string",
                          "const": "file"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "file: declared in that deployment's vestra.yaml, so deploying the file changes it; null: you made it."
                    },
                    "created_at": {
                      "type": "string",
                      "description": "When it was made, as an ISO 8601 time."
                    },
                    "updated_at": {
                      "type": "string",
                      "description": "When it last changed, as an ISO 8601 time."
                    }
                  },
                  "required": [
                    "id",
                    "object",
                    "url",
                    "events",
                    "description",
                    "active",
                    "mode",
                    "deployment_id",
                    "managed_by",
                    "created_at",
                    "updated_at"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "url": {
                    "description": "A new public https URL.",
                    "type": "string",
                    "maxLength": 2048,
                    "format": "uri"
                  },
                  "events": {
                    "description": "The events it wants now: 1 to 40 types, or * for all.",
                    "minItems": 1,
                    "maxItems": 40,
                    "type": "array",
                    "items": {
                      "anyOf": [
                        {
                          "type": "string",
                          "enum": [
                            "message.completed",
                            "task.started",
                            "task.completed",
                            "task.failed",
                            "task.stopped",
                            "interaction.created",
                            "interaction.resolved",
                            "interaction.expired",
                            "session.started",
                            "session.ended",
                            "file.created",
                            "routine.fired",
                            "usage.threshold_reached",
                            "usage.cap_reached",
                            "conversation.status",
                            "user.created",
                            "user.deleted",
                            "connection.completed",
                            "connection.failed",
                            "connection.removed",
                            "memory.observed",
                            "batch.completed",
                            "deployment.version_created",
                            "deployment.promoted",
                            "deployment.rolled_back",
                            "test_run.completed",
                            "key.created",
                            "key.revoked"
                          ],
                          "description": "An event a webhook carries: every event of the catalog but the six that ride only the stream (message.delta, task.progress, usage.updated, screen.control, error and ping).",
                          "examples": [
                            "task.completed"
                          ]
                        },
                        {
                          "type": "string",
                          "const": "*"
                        }
                      ],
                      "description": "An event the endpoint wants, by its type, or * for every event a webhook carries.",
                      "examples": [
                        "task.completed"
                      ]
                    }
                  },
                  "description": {
                    "description": "A new note; null clears it.",
                    "anyOf": [
                      {
                        "type": "string",
                        "maxLength": 500
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "active": {
                    "description": "false stops sending to it, until you set true again.",
                    "type": "boolean"
                  }
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteWebhooksByEndpointId",
        "summary": "Remove it.",
        "tags": [
          "Webhooks and events"
        ],
        "x-vestra-line": "events",
        "x-vestra-scope": "setup",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "endpoint_id",
            "in": "path",
            "required": true,
            "description": "The webhook endpoint's id (`whk_...`).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "The endpoint (whk_...)."
                    },
                    "object": {
                      "type": "string",
                      "const": "webhook_endpoint",
                      "description": "Always webhook_endpoint."
                    },
                    "deleted": {
                      "type": "boolean",
                      "const": true,
                      "description": "Always true: nothing more is sent to it."
                    }
                  },
                  "required": [
                    "id",
                    "object",
                    "deleted"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/webhooks/{endpoint_id}/roll-secret": {
      "post": {
        "operationId": "postWebhooksByEndpointIdRollSecret",
        "summary": "New signing secret; the old one is accepted for 24 hours.",
        "tags": [
          "Webhooks and events"
        ],
        "x-vestra-line": "events",
        "x-vestra-scope": "setup",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "endpoint_id",
            "in": "path",
            "required": true,
            "description": "The webhook endpoint's id (`whk_...`).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "The endpoint (whk_...).",
                      "examples": [
                        "whk_2bq"
                      ]
                    },
                    "object": {
                      "type": "string",
                      "const": "webhook_endpoint",
                      "description": "Always webhook_endpoint."
                    },
                    "url": {
                      "type": "string",
                      "description": "Where the events go."
                    },
                    "events": {
                      "type": "array",
                      "items": {
                        "anyOf": [
                          {
                            "type": "string",
                            "enum": [
                              "message.completed",
                              "task.started",
                              "task.completed",
                              "task.failed",
                              "task.stopped",
                              "interaction.created",
                              "interaction.resolved",
                              "interaction.expired",
                              "session.started",
                              "session.ended",
                              "file.created",
                              "routine.fired",
                              "usage.threshold_reached",
                              "usage.cap_reached",
                              "conversation.status",
                              "user.created",
                              "user.deleted",
                              "connection.completed",
                              "connection.failed",
                              "connection.removed",
                              "memory.observed",
                              "batch.completed",
                              "deployment.version_created",
                              "deployment.promoted",
                              "deployment.rolled_back",
                              "test_run.completed",
                              "key.created",
                              "key.revoked"
                            ],
                            "description": "An event a webhook carries: every event of the catalog but the six that ride only the stream (message.delta, task.progress, usage.updated, screen.control, error and ping).",
                            "examples": [
                              "task.completed"
                            ]
                          },
                          {
                            "type": "string",
                            "const": "*"
                          }
                        ],
                        "description": "An event the endpoint wants, by its type, or * for every event a webhook carries.",
                        "examples": [
                          "task.completed"
                        ]
                      },
                      "description": "The events it wants."
                    },
                    "description": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Your note; null when you gave none."
                    },
                    "active": {
                      "type": "boolean",
                      "description": "Whether events are sent to it."
                    },
                    "mode": {
                      "type": "string",
                      "enum": [
                        "live",
                        "test"
                      ],
                      "description": "The mode it hears: test or live, the mode of the key that made it. A test endpoint never hears a live event."
                    },
                    "deployment_id": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Only this deployment's events reach it (dep_...), plus your account's, such as keys, users and usage alerts. Set when a deployment's vestra.yaml declared the endpoint. Null: every event its types allow."
                    },
                    "managed_by": {
                      "anyOf": [
                        {
                          "type": "string",
                          "const": "file"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "file: declared in that deployment's vestra.yaml, so deploying the file changes it; null: you made it."
                    },
                    "created_at": {
                      "type": "string",
                      "description": "When it was made, as an ISO 8601 time."
                    },
                    "updated_at": {
                      "type": "string",
                      "description": "When it last changed, as an ISO 8601 time."
                    },
                    "secret": {
                      "type": "string",
                      "description": "The signing secret, shown this once: check every delivery against it (the Vestra-Signature header). Keep it on your server.",
                      "examples": [
                        "whsec_..."
                      ]
                    }
                  },
                  "required": [
                    "id",
                    "object",
                    "url",
                    "events",
                    "description",
                    "active",
                    "mode",
                    "deployment_id",
                    "managed_by",
                    "created_at",
                    "updated_at",
                    "secret"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/webhooks/{endpoint_id}/test": {
      "post": {
        "operationId": "postWebhooksByEndpointIdTest",
        "summary": "Send a sample event now.",
        "tags": [
          "Webhooks and events"
        ],
        "x-vestra-line": "events",
        "x-vestra-scope": "setup",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "endpoint_id",
            "in": "path",
            "required": true,
            "description": "The webhook endpoint's id (`whk_...`).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 255
            },
            "description": "Send the same key to retry this call safely for 24 hours."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "description": "Whether your endpoint answered 2xx to a signed webhook.test event."
                    },
                    "status_code": {
                      "anyOf": [
                        {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "What it answered; null when it did not answer."
                    },
                    "duration_ms": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991,
                      "description": "How long it took, in milliseconds: 10 seconds at most."
                    },
                    "error": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "What went wrong, such as a timeout; null when it answered."
                    }
                  },
                  "required": [
                    "ok",
                    "status_code",
                    "duration_ms",
                    "error"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/webhooks/{endpoint_id}/deliveries": {
      "get": {
        "operationId": "getWebhooksByEndpointIdDeliveries",
        "summary": "Every attempt with status code and timing.",
        "tags": [
          "Webhooks and events"
        ],
        "x-vestra-line": "events",
        "x-vestra-scope": "setup",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "endpoint_id",
            "in": "path",
            "required": true,
            "description": "The webhook endpoint's id (`whk_...`).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "default": 20,
              "description": "How many items per page, 1 to 100. Default 20.",
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "description": "Where to go on from: the `next_cursor` of the page before, unchanged. Absent: the first page.",
              "type": "string"
            }
          },
          {
            "name": "state",
            "in": "query",
            "required": false,
            "schema": {
              "description": "Only deliveries in this state.",
              "type": "string",
              "enum": [
                "pending",
                "sending",
                "sent",
                "failed"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "The delivery: one event, to one endpoint (dlv_...)."
                          },
                          "object": {
                            "type": "string",
                            "const": "webhook_delivery",
                            "description": "Always webhook_delivery."
                          },
                          "endpoint_id": {
                            "type": "string",
                            "description": "The endpoint (whk_...)."
                          },
                          "event_id": {
                            "type": "string",
                            "description": "The event (evt_...): read it again with GET /v1/events."
                          },
                          "event_type": {
                            "anyOf": [
                              {
                                "type": "string",
                                "enum": [
                                  "message.completed",
                                  "task.started",
                                  "task.completed",
                                  "task.failed",
                                  "task.stopped",
                                  "interaction.created",
                                  "interaction.resolved",
                                  "interaction.expired",
                                  "session.started",
                                  "session.ended",
                                  "file.created",
                                  "routine.fired",
                                  "usage.threshold_reached",
                                  "usage.cap_reached",
                                  "conversation.status",
                                  "user.created",
                                  "user.deleted",
                                  "connection.completed",
                                  "connection.failed",
                                  "connection.removed",
                                  "memory.observed",
                                  "batch.completed",
                                  "deployment.version_created",
                                  "deployment.promoted",
                                  "deployment.rolled_back",
                                  "test_run.completed",
                                  "key.created",
                                  "key.revoked"
                                ],
                                "description": "An event a webhook carries: every event of the catalog but the six that ride only the stream (message.delta, task.progress, usage.updated, screen.control, error and ping).",
                                "examples": [
                                  "task.completed"
                                ]
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "The event's type; null when the event is gone."
                          },
                          "state": {
                            "type": "string",
                            "enum": [
                              "pending",
                              "sending",
                              "sent",
                              "failed"
                            ],
                            "description": "pending: waiting for its next try. sending: being sent now. sent: your endpoint answered 2xx. failed: it gave up: after 5 tries, or when the endpoint was turned off or the event is gone."
                          },
                          "attempts": {
                            "type": "integer",
                            "minimum": -9007199254740991,
                            "maximum": 9007199254740991,
                            "description": "How many times it has been tried: 5 at most, waiting 1, 5, 15 and then 60 minutes between them."
                          },
                          "next_attempt_at": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "When it is tried next, as an ISO 8601 time; null when it will not be."
                          },
                          "last_status_code": {
                            "anyOf": [
                              {
                                "type": "integer",
                                "minimum": -9007199254740991,
                                "maximum": 9007199254740991
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "What your endpoint last answered; null when it never answered."
                          },
                          "last_error": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "What last went wrong; null when nothing did."
                          },
                          "attempt_log": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "at": {
                                  "type": "string",
                                  "description": "When it was tried, as an ISO 8601 time."
                                },
                                "status_code": {
                                  "anyOf": [
                                    {
                                      "type": "integer",
                                      "minimum": -9007199254740991,
                                      "maximum": 9007199254740991
                                    },
                                    {
                                      "type": "null"
                                    }
                                  ],
                                  "description": "What your endpoint answered; null when it did not answer."
                                },
                                "duration_ms": {
                                  "type": "integer",
                                  "minimum": -9007199254740991,
                                  "maximum": 9007199254740991,
                                  "description": "How long the try took, in milliseconds: a try waits 10 seconds at most."
                                },
                                "error": {
                                  "anyOf": [
                                    {
                                      "type": "string"
                                    },
                                    {
                                      "type": "null"
                                    }
                                  ],
                                  "description": "What went wrong, such as a timeout; null when it was sent."
                                }
                              },
                              "required": [
                                "at",
                                "status_code",
                                "duration_ms",
                                "error"
                              ]
                            },
                            "description": "Every try, oldest first."
                          },
                          "created_at": {
                            "type": "string",
                            "description": "When the event was queued for this endpoint, as an ISO 8601 time."
                          },
                          "sent_at": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "When your endpoint took it, as an ISO 8601 time; null until then."
                          }
                        },
                        "required": [
                          "id",
                          "object",
                          "endpoint_id",
                          "event_id",
                          "event_type",
                          "state",
                          "attempts",
                          "next_attempt_at",
                          "last_status_code",
                          "last_error",
                          "attempt_log",
                          "created_at",
                          "sent_at"
                        ]
                      },
                      "description": "The items on this page."
                    },
                    "next_cursor": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Send it as `cursor` for the next page; null on the last page."
                    }
                  },
                  "required": [
                    "data",
                    "next_cursor"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/webhooks/{endpoint_id}/deliveries/{delivery_id}/retry": {
      "post": {
        "operationId": "postWebhooksByEndpointIdDeliveriesByDeliveryIdRetry",
        "summary": "Send one again.",
        "tags": [
          "Webhooks and events"
        ],
        "x-vestra-line": "events",
        "x-vestra-scope": "setup",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "endpoint_id",
            "in": "path",
            "required": true,
            "description": "The webhook endpoint's id (`whk_...`).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "delivery_id",
            "in": "path",
            "required": true,
            "description": "The delivery's id (`dlv_...`).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 255
            },
            "description": "Send the same key to retry this call safely for 24 hours."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "The delivery: one event, to one endpoint (dlv_...)."
                    },
                    "object": {
                      "type": "string",
                      "const": "webhook_delivery",
                      "description": "Always webhook_delivery."
                    },
                    "endpoint_id": {
                      "type": "string",
                      "description": "The endpoint (whk_...)."
                    },
                    "event_id": {
                      "type": "string",
                      "description": "The event (evt_...): read it again with GET /v1/events."
                    },
                    "event_type": {
                      "anyOf": [
                        {
                          "type": "string",
                          "enum": [
                            "message.completed",
                            "task.started",
                            "task.completed",
                            "task.failed",
                            "task.stopped",
                            "interaction.created",
                            "interaction.resolved",
                            "interaction.expired",
                            "session.started",
                            "session.ended",
                            "file.created",
                            "routine.fired",
                            "usage.threshold_reached",
                            "usage.cap_reached",
                            "conversation.status",
                            "user.created",
                            "user.deleted",
                            "connection.completed",
                            "connection.failed",
                            "connection.removed",
                            "memory.observed",
                            "batch.completed",
                            "deployment.version_created",
                            "deployment.promoted",
                            "deployment.rolled_back",
                            "test_run.completed",
                            "key.created",
                            "key.revoked"
                          ],
                          "description": "An event a webhook carries: every event of the catalog but the six that ride only the stream (message.delta, task.progress, usage.updated, screen.control, error and ping).",
                          "examples": [
                            "task.completed"
                          ]
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The event's type; null when the event is gone."
                    },
                    "state": {
                      "type": "string",
                      "enum": [
                        "pending",
                        "sending",
                        "sent",
                        "failed"
                      ],
                      "description": "pending: waiting for its next try. sending: being sent now. sent: your endpoint answered 2xx. failed: it gave up: after 5 tries, or when the endpoint was turned off or the event is gone."
                    },
                    "attempts": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991,
                      "description": "How many times it has been tried: 5 at most, waiting 1, 5, 15 and then 60 minutes between them."
                    },
                    "next_attempt_at": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "When it is tried next, as an ISO 8601 time; null when it will not be."
                    },
                    "last_status_code": {
                      "anyOf": [
                        {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "What your endpoint last answered; null when it never answered."
                    },
                    "last_error": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "What last went wrong; null when nothing did."
                    },
                    "attempt_log": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "at": {
                            "type": "string",
                            "description": "When it was tried, as an ISO 8601 time."
                          },
                          "status_code": {
                            "anyOf": [
                              {
                                "type": "integer",
                                "minimum": -9007199254740991,
                                "maximum": 9007199254740991
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "What your endpoint answered; null when it did not answer."
                          },
                          "duration_ms": {
                            "type": "integer",
                            "minimum": -9007199254740991,
                            "maximum": 9007199254740991,
                            "description": "How long the try took, in milliseconds: a try waits 10 seconds at most."
                          },
                          "error": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "What went wrong, such as a timeout; null when it was sent."
                          }
                        },
                        "required": [
                          "at",
                          "status_code",
                          "duration_ms",
                          "error"
                        ]
                      },
                      "description": "Every try, oldest first."
                    },
                    "created_at": {
                      "type": "string",
                      "description": "When the event was queued for this endpoint, as an ISO 8601 time."
                    },
                    "sent_at": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "When your endpoint took it, as an ISO 8601 time; null until then."
                    }
                  },
                  "required": [
                    "id",
                    "object",
                    "endpoint_id",
                    "event_id",
                    "event_type",
                    "state",
                    "attempts",
                    "next_attempt_at",
                    "last_status_code",
                    "last_error",
                    "attempt_log",
                    "created_at",
                    "sent_at"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/events": {
      "get": {
        "operationId": "getEvents",
        "summary": "The same events as a list you can pull, for anything you missed.",
        "tags": [
          "Webhooks and events"
        ],
        "x-vestra-line": "events",
        "x-vestra-scope": "runtime",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "default": 20,
              "description": "How many items per page, 1 to 100. Default 20.",
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "description": "Where to go on from: the `next_cursor` of the page before, unchanged. Absent: the first page.",
              "type": "string"
            }
          },
          {
            "name": "type",
            "in": "query",
            "required": false,
            "schema": {
              "description": "Only events of this type.",
              "type": "string",
              "enum": [
                "message.completed",
                "task.started",
                "task.completed",
                "task.failed",
                "task.stopped",
                "interaction.created",
                "interaction.resolved",
                "interaction.expired",
                "session.started",
                "session.ended",
                "file.created",
                "routine.fired",
                "usage.threshold_reached",
                "usage.cap_reached",
                "conversation.status",
                "user.created",
                "user.deleted",
                "connection.completed",
                "connection.failed",
                "connection.removed",
                "memory.observed",
                "batch.completed",
                "deployment.version_created",
                "deployment.promoted",
                "deployment.rolled_back",
                "test_run.completed",
                "key.created",
                "key.revoked"
              ],
              "examples": [
                "task.completed"
              ]
            }
          },
          {
            "name": "user_id",
            "in": "query",
            "required": false,
            "schema": {
              "description": "Only this user's, by your id for them.",
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "task_id",
            "in": "query",
            "required": false,
            "schema": {
              "description": "Only this task's (task_...).",
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "created_after",
            "in": "query",
            "required": false,
            "schema": {
              "description": "Only events after this ISO 8601 time.",
              "type": "string",
              "format": "date-time",
              "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
            }
          },
          {
            "name": "created_before",
            "in": "query",
            "required": false,
            "schema": {
              "description": "Only events before this ISO 8601 time.",
              "type": "string",
              "format": "date-time",
              "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
            }
          },
          {
            "name": "after",
            "in": "query",
            "required": false,
            "schema": {
              "description": "Only events after this one (evt_...), oldest first: poll with the last one you saw and you miss nothing. Without it, newest first.",
              "examples": [
                "evt_4hq"
              ],
              "type": "string",
              "minLength": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "The event (evt_...): the same on every retry, so use it to skip one you already took.",
                            "examples": [
                              "evt_4hq"
                            ]
                          },
                          "object": {
                            "type": "string",
                            "const": "event",
                            "description": "Always event."
                          },
                          "type": {
                            "type": "string",
                            "enum": [
                              "message.completed",
                              "task.started",
                              "task.completed",
                              "task.failed",
                              "task.stopped",
                              "interaction.created",
                              "interaction.resolved",
                              "interaction.expired",
                              "session.started",
                              "session.ended",
                              "file.created",
                              "routine.fired",
                              "usage.threshold_reached",
                              "usage.cap_reached",
                              "conversation.status",
                              "user.created",
                              "user.deleted",
                              "connection.completed",
                              "connection.failed",
                              "connection.removed",
                              "memory.observed",
                              "batch.completed",
                              "deployment.version_created",
                              "deployment.promoted",
                              "deployment.rolled_back",
                              "test_run.completed",
                              "key.created",
                              "key.revoked"
                            ],
                            "description": "An event a webhook carries: every event of the catalog but the six that ride only the stream (message.delta, task.progress, usage.updated, screen.control, error and ping).",
                            "examples": [
                              "task.completed"
                            ]
                          },
                          "mode": {
                            "type": "string",
                            "enum": [
                              "live",
                              "test"
                            ],
                            "description": "The mode it happened in: test or live."
                          },
                          "created_at": {
                            "type": "string",
                            "description": "When it happened, as an ISO 8601 time."
                          },
                          "user_id": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "Your id for the user it concerns; null for your company's own Bash, or when it concerns no user."
                          },
                          "task_id": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "The task it concerns (task_...); null when none."
                          },
                          "conversation_id": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "The conversation it concerns (conv_...); null when none."
                          },
                          "data": {
                            "type": "object",
                            "propertyNames": {
                              "type": "string"
                            },
                            "additionalProperties": {},
                            "description": "What it says: its fields depend on its type, as the events reference lists them."
                          }
                        },
                        "required": [
                          "id",
                          "object",
                          "type",
                          "mode",
                          "created_at",
                          "user_id",
                          "task_id",
                          "conversation_id",
                          "data"
                        ]
                      },
                      "description": "The items on this page."
                    },
                    "next_cursor": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Send it as `cursor` for the next page; null on the last page."
                    }
                  },
                  "required": [
                    "data",
                    "next_cursor"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/events/{event_id}": {
      "get": {
        "operationId": "getEventsByEventId",
        "summary": "One event.",
        "tags": [
          "Webhooks and events"
        ],
        "x-vestra-line": "events",
        "x-vestra-scope": "runtime",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "event_id",
            "in": "path",
            "required": true,
            "description": "The event's id (`evt_...`).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "The event (evt_...): the same on every retry, so use it to skip one you already took.",
                      "examples": [
                        "evt_4hq"
                      ]
                    },
                    "object": {
                      "type": "string",
                      "const": "event",
                      "description": "Always event."
                    },
                    "type": {
                      "type": "string",
                      "enum": [
                        "message.completed",
                        "task.started",
                        "task.completed",
                        "task.failed",
                        "task.stopped",
                        "interaction.created",
                        "interaction.resolved",
                        "interaction.expired",
                        "session.started",
                        "session.ended",
                        "file.created",
                        "routine.fired",
                        "usage.threshold_reached",
                        "usage.cap_reached",
                        "conversation.status",
                        "user.created",
                        "user.deleted",
                        "connection.completed",
                        "connection.failed",
                        "connection.removed",
                        "memory.observed",
                        "batch.completed",
                        "deployment.version_created",
                        "deployment.promoted",
                        "deployment.rolled_back",
                        "test_run.completed",
                        "key.created",
                        "key.revoked"
                      ],
                      "description": "An event a webhook carries: every event of the catalog but the six that ride only the stream (message.delta, task.progress, usage.updated, screen.control, error and ping).",
                      "examples": [
                        "task.completed"
                      ]
                    },
                    "mode": {
                      "type": "string",
                      "enum": [
                        "live",
                        "test"
                      ],
                      "description": "The mode it happened in: test or live."
                    },
                    "created_at": {
                      "type": "string",
                      "description": "When it happened, as an ISO 8601 time."
                    },
                    "user_id": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Your id for the user it concerns; null for your company's own Bash, or when it concerns no user."
                    },
                    "task_id": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The task it concerns (task_...); null when none."
                    },
                    "conversation_id": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The conversation it concerns (conv_...); null when none."
                    },
                    "data": {
                      "type": "object",
                      "propertyNames": {
                        "type": "string"
                      },
                      "additionalProperties": {},
                      "description": "What it says: its fields depend on its type, as the events reference lists them."
                    }
                  },
                  "required": [
                    "id",
                    "object",
                    "type",
                    "mode",
                    "created_at",
                    "user_id",
                    "task_id",
                    "conversation_id",
                    "data"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/sessions": {
      "post": {
        "operationId": "postSessions",
        "summary": "Open a session for one of your users (user_id), or for the company's own Bash: chat, a screen to watch or drive, a voice call, and what Bash remembers (memory, when your company turned the panel on). Answers a 15 minute token for the user's browser, a ready page url and the sites allowed to frame it. The token reaches only that user, and only the session's conversation.",
        "tags": [
          "Sessions"
        ],
        "x-vestra-line": "embed",
        "x-vestra-scope": "runtime",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [],
        "responses": {
          "201": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "The session (ses_...).",
                      "examples": [
                        "ses_8h2"
                      ]
                    },
                    "object": {
                      "type": "string",
                      "const": "session",
                      "description": "Always session."
                    },
                    "user_id": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Your id for its user; null on your company's own Bash."
                    },
                    "conversation_id": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Its conversation (conv_...); null for a screen opened alone."
                    },
                    "chat": {
                      "type": "boolean",
                      "description": "Whether it shows the conversation."
                    },
                    "screen": {
                      "anyOf": [
                        {
                          "type": "boolean",
                          "const": false
                        },
                        {
                          "type": "string",
                          "enum": [
                            "view",
                            "control"
                          ]
                        }
                      ],
                      "description": "Its screen: view, control, or false for none."
                    },
                    "voice": {
                      "type": "boolean",
                      "description": "Whether your user can talk by voice."
                    },
                    "memory": {
                      "type": "boolean",
                      "description": "Whether it shows what Bash remembers."
                    },
                    "token": {
                      "type": "string",
                      "description": "The session's own token, shown this once and good for 15 minutes. It reaches this user's session and conversation only: messages, events, approvals, files and memory. Never your account, keys or usage."
                    },
                    "url": {
                      "type": "string",
                      "description": "The page to show your user, in a tab or an iframe; it carries the token."
                    },
                    "frame_ancestors": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "The sites that may frame the page: your company's allowed_embed_origins. Empty: it opens only as a page of its own."
                    },
                    "expires_at": {
                      "type": "string",
                      "description": "When the token stops working, 15 minutes after it was made, as an ISO 8601 time."
                    }
                  },
                  "required": [
                    "id",
                    "object",
                    "user_id",
                    "conversation_id",
                    "chat",
                    "screen",
                    "voice",
                    "memory",
                    "token",
                    "url",
                    "frame_ancestors",
                    "expires_at"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "user_id": {
                    "description": "Your id for the user this session is for. Absent: your company's own Bash.",
                    "examples": [
                      "traveller-42"
                    ],
                    "type": "string",
                    "pattern": "^[A-Za-z0-9][A-Za-z0-9._:@-]{0,127}$"
                  },
                  "conversation_id": {
                    "description": "A conversation of that user's to open it in (conv_...). Absent, with chat or voice: a new conversation on the user's default deployment, then your company's.",
                    "type": "string",
                    "minLength": 1
                  },
                  "chat": {
                    "default": false,
                    "description": "Show the conversation, so your user can talk to Bash and answer its approvals. Default: false.",
                    "type": "boolean"
                  },
                  "screen": {
                    "default": false,
                    "description": "Show Bash's screen: view to watch it, control to also take the wheel. Default: false, no screen.",
                    "anyOf": [
                      {
                        "type": "boolean",
                        "const": false
                      },
                      {
                        "type": "string",
                        "enum": [
                          "view",
                          "control"
                        ]
                      }
                    ]
                  },
                  "voice": {
                    "default": false,
                    "description": "Let your user talk to Bash by voice: true, or a voice by name. Default: false.",
                    "anyOf": [
                      {
                        "type": "boolean"
                      },
                      {
                        "type": "object",
                        "properties": {
                          "voice": {
                            "type": "string",
                            "minLength": 1,
                            "description": "Which voice Bash speaks in, such as marin (the default) or quartz."
                          }
                        },
                        "required": [
                          "voice"
                        ]
                      }
                    ]
                  },
                  "memory": {
                    "default": false,
                    "description": "Show what Bash remembers about your user. Your company must turn it on first (PATCH /v1/org, memory_panel: true). Default: false.",
                    "type": "boolean"
                  },
                  "driver": {
                    "description": "With screen: control, who drives when the screen opens. bash (the default): your user watches and taps Take control. user: your user drives from the first frame the page shows, with no Take control and nothing to give back, for a page that is theirs to use (a sign-in Bash opened for them).",
                    "type": "string",
                    "enum": [
                      "bash",
                      "user"
                    ]
                  }
                },
                "additionalProperties": false
              }
            }
          }
        }
      }
    },
    "/v1/sessions/{session_id}": {
      "get": {
        "operationId": "getSessionsBySessionId",
        "summary": "Whether a session is still open, and what it was opened with. Your key, or the session's own token.",
        "tags": [
          "Sessions"
        ],
        "x-vestra-line": "embed",
        "x-vestra-scope": "runtime",
        "security": [
          {
            "apiKey": []
          },
          {
            "clientToken": []
          }
        ],
        "parameters": [
          {
            "name": "session_id",
            "in": "path",
            "required": true,
            "description": "The session's id (`ses_...`).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "The session (ses_...).",
                      "examples": [
                        "ses_8h2"
                      ]
                    },
                    "object": {
                      "type": "string",
                      "const": "session",
                      "description": "Always session."
                    },
                    "user_id": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Your id for its user; null on your company's own Bash."
                    },
                    "conversation_id": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Its conversation (conv_...); null for a screen opened alone."
                    },
                    "chat": {
                      "type": "boolean",
                      "description": "Whether it shows the conversation."
                    },
                    "screen": {
                      "anyOf": [
                        {
                          "type": "boolean",
                          "const": false
                        },
                        {
                          "type": "string",
                          "enum": [
                            "view",
                            "control"
                          ]
                        }
                      ],
                      "description": "Its screen: view, control, or false for none."
                    },
                    "voice": {
                      "type": "boolean",
                      "description": "Whether your user can talk by voice."
                    },
                    "memory": {
                      "type": "boolean",
                      "description": "Whether it shows what Bash remembers."
                    },
                    "expires_at": {
                      "type": "string",
                      "description": "When the token stops working, 15 minutes after it was made, as an ISO 8601 time."
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "live",
                        "expired",
                        "revoked"
                      ],
                      "description": "live: its token works. expired: its 15 minutes are up. revoked: it was ended early."
                    },
                    "screen_paused": {
                      "description": "A view-only screen while it is private: a person signs in on that computer (a browser fetch with front, a hand-off), or a private fetch runs or keeps its tab. Nothing shows, and GET /v1/sessions/{session_id}/screen answers 409 browser_in_use, until it is done. Absent otherwise.",
                      "type": "boolean",
                      "const": true
                    }
                  },
                  "required": [
                    "id",
                    "object",
                    "user_id",
                    "conversation_id",
                    "chat",
                    "screen",
                    "voice",
                    "memory",
                    "expires_at",
                    "status"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteSessionsBySessionId",
        "summary": "End a session now: its token stops working, its streams close and its call hangs up. Your key, or the session's own token.",
        "tags": [
          "Sessions"
        ],
        "x-vestra-line": "embed",
        "x-vestra-scope": "runtime",
        "security": [
          {
            "apiKey": []
          },
          {
            "clientToken": []
          }
        ],
        "parameters": [
          {
            "name": "session_id",
            "in": "path",
            "required": true,
            "description": "The session's id (`ses_...`).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "The session (ses_...).",
                      "examples": [
                        "ses_8h2"
                      ]
                    },
                    "object": {
                      "type": "string",
                      "const": "session",
                      "description": "Always session."
                    },
                    "user_id": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Your id for its user; null on your company's own Bash."
                    },
                    "conversation_id": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Its conversation (conv_...); null for a screen opened alone."
                    },
                    "chat": {
                      "type": "boolean",
                      "description": "Whether it shows the conversation."
                    },
                    "screen": {
                      "anyOf": [
                        {
                          "type": "boolean",
                          "const": false
                        },
                        {
                          "type": "string",
                          "enum": [
                            "view",
                            "control"
                          ]
                        }
                      ],
                      "description": "Its screen: view, control, or false for none."
                    },
                    "voice": {
                      "type": "boolean",
                      "description": "Whether your user can talk by voice."
                    },
                    "memory": {
                      "type": "boolean",
                      "description": "Whether it shows what Bash remembers."
                    },
                    "expires_at": {
                      "type": "string",
                      "description": "When the token stops working, 15 minutes after it was made, as an ISO 8601 time."
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "live",
                        "expired",
                        "revoked"
                      ],
                      "description": "live: its token works. expired: its 15 minutes are up. revoked: it was ended early."
                    },
                    "screen_paused": {
                      "description": "A view-only screen while it is private: a person signs in on that computer (a browser fetch with front, a hand-off), or a private fetch runs or keeps its tab. Nothing shows, and GET /v1/sessions/{session_id}/screen answers 409 browser_in_use, until it is done. Absent otherwise.",
                      "type": "boolean",
                      "const": true
                    }
                  },
                  "required": [
                    "id",
                    "object",
                    "user_id",
                    "conversation_id",
                    "chat",
                    "screen",
                    "voice",
                    "memory",
                    "expires_at",
                    "status"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/sessions/{session_id}/frame-policy": {
      "get": {
        "operationId": "getSessionsBySessionIdFramePolicy",
        "summary": "Which sites may show a session's page. The page asks this itself; you never need to.",
        "tags": [
          "Sessions"
        ],
        "x-vestra-line": "embed",
        "security": [],
        "parameters": [
          {
            "name": "session_id",
            "in": "path",
            "required": true,
            "description": "The session's id (`ses_...`).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "type": "string",
                      "const": "frame_policy",
                      "description": "Always frame_policy."
                    },
                    "frame_ancestors": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "The sites that may frame the session's page; empty when it may open only as a page of its own."
                    }
                  },
                  "required": [
                    "object",
                    "frame_ancestors"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/sessions/{session_id}/screen": {
      "get": {
        "operationId": "getSessionsBySessionIdScreen",
        "summary": "With the session's token: the stream credentials of the user's Bash browser, good for 5 minutes. For a session opened with a screen. 409 payment_in_progress while the person pays for something in their browser.",
        "tags": [
          "Sessions"
        ],
        "x-vestra-line": "watch",
        "security": [
          {
            "clientToken": []
          }
        ],
        "parameters": [
          {
            "name": "session_id",
            "in": "path",
            "required": true,
            "description": "The session's id (`ses_...`).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "type": "string",
                      "const": "browser_stream",
                      "description": "Always browser_stream."
                    },
                    "neko_url": {
                      "type": "string",
                      "description": "The address of the screen's stream."
                    },
                    "preview_token": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "A second token the stream address asks for, when it asks for one; null otherwise."
                    },
                    "preview_token_param": {
                      "description": "The query parameter preview_token goes in, on the stream address and its picture. Absent: bl_preview_token.",
                      "examples": [
                        "_token"
                      ],
                      "type": "string"
                    },
                    "neko_token": {
                      "type": "string",
                      "description": "The token for the screen's stream: good for 5 minutes, so read this again for a fresh one."
                    },
                    "ice_servers": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "urls": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            },
                            "description": "The server's addresses (stun: or turn:)."
                          },
                          "username": {
                            "description": "Its username, for a TURN server.",
                            "type": "string"
                          },
                          "credential": {
                            "description": "Its password, for a TURN server.",
                            "type": "string"
                          }
                        },
                        "required": [
                          "urls"
                        ]
                      },
                      "description": "Servers that help the WebRTC connection to the screen through firewalls; empty when none are set."
                    },
                    "width": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991,
                      "description": "The screen's width in pixels.",
                      "examples": [
                        1440
                      ]
                    },
                    "height": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991,
                      "description": "The screen's height in pixels.",
                      "examples": [
                        900
                      ]
                    },
                    "crop": {
                      "description": "While a hand-off is open on the screen (a browser fetch with front, such as a sign-in): the part of the screen its page fills, at a phone's size, or only the element its front_crop named. Show only this part, and map taps into it. Absent: show the whole screen.",
                      "type": "object",
                      "properties": {
                        "x": {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991,
                          "description": "Its left edge, in screen pixels."
                        },
                        "y": {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991,
                          "description": "Its top edge, in screen pixels."
                        },
                        "width": {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991,
                          "description": "Its width, in screen pixels."
                        },
                        "height": {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991,
                          "description": "Its height, in screen pixels."
                        }
                      },
                      "required": [
                        "x",
                        "y",
                        "width",
                        "height"
                      ]
                    },
                    "crop_pending": {
                      "description": "A hand-off's front_crop is not on its page yet (for up to 20 seconds from its start): show no picture yet, and read this again in a couple of seconds for its crop. Absent: crop says what to show.",
                      "type": "boolean",
                      "const": true
                    }
                  },
                  "required": [
                    "object",
                    "neko_url",
                    "preview_token",
                    "neko_token",
                    "ice_servers",
                    "width",
                    "height"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "postSessionsBySessionIdScreen",
        "summary": "With the session's token, in control mode: the user takes the wheel or gives it back (action), or says they are driving (input), so Bash waits.",
        "tags": [
          "Sessions"
        ],
        "x-vestra-line": "watch",
        "security": [
          {
            "clientToken": []
          }
        ],
        "parameters": [
          {
            "name": "session_id",
            "in": "path",
            "required": true,
            "description": "The session's id (`ses_...`).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "anyOf": [
                    {
                      "type": "object",
                      "properties": {
                        "object": {
                          "type": "string",
                          "const": "screen_control",
                          "description": "Always screen_control."
                        },
                        "by": {
                          "type": "string",
                          "enum": [
                            "user",
                            "bash"
                          ],
                          "description": "Who drives the screen now: user, the person, or bash."
                        }
                      },
                      "required": [
                        "object",
                        "by"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "object": {
                          "type": "string",
                          "const": "screen_input",
                          "description": "Always screen_input."
                        },
                        "delivered": {
                          "type": "boolean",
                          "description": "Whether Bash's computer heard it; false when it is not connected."
                        }
                      },
                      "required": [
                        "object",
                        "delivered"
                      ]
                    }
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "anyOf": [
                  {
                    "type": "object",
                    "properties": {
                      "action": {
                        "type": "string",
                        "enum": [
                          "take",
                          "give_back"
                        ],
                        "description": "take: the person takes the wheel and Bash waits. give_back: Bash drives again."
                      }
                    },
                    "required": [
                      "action"
                    ],
                    "additionalProperties": false
                  },
                  {
                    "type": "object",
                    "properties": {
                      "input": {
                        "type": "boolean",
                        "const": true,
                        "description": "The person is typing or clicking now: Bash holds off while these keep coming, each good for a few seconds."
                      }
                    },
                    "required": [
                      "input"
                    ],
                    "additionalProperties": false
                  }
                ]
              }
            }
          }
        }
      }
    },
    "/v1/users/{user_id}/screenshot": {
      "get": {
        "operationId": "getUsersByUserIdScreenshot",
        "summary": "The latest frame of the user's browser, as a JPEG. 409 browser_in_use while a person finishes a sign-in on it (a browser fetch with front open): its page is for them alone. 409 payment_in_progress while the person pays for something in their browser, or just after.",
        "tags": [
          "Sessions"
        ],
        "x-vestra-line": "watch",
        "x-vestra-scope": "runtime",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "user_id",
            "in": "path",
            "required": true,
            "description": "Your own id for the user, as you named them.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "image/jpeg": {
                "schema": {
                  "type": "string",
                  "contentMediaType": "image/jpeg"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/users/{user_id}/browser/cookies": {
      "get": {
        "operationId": "getUsersByUserIdBrowserCookies",
        "summary": "Which cookies of some names the user's browser holds for one site, and until when: names, sites and expiry only, never a value. Only a site on the deployment's browser.allowed_domains (403 domain_not_allowed). Opens no page and acts on nothing, so it never disturbs a person using the browser: read it every few seconds to see a person finish signing in on a page you handed them (front), as the site's session cookie appears or its expiry moves on. Wakes the computer when it sleeps.",
        "tags": [
          "Computer setup"
        ],
        "x-vestra-line": "users",
        "x-vestra-scope": "runtime",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "user_id",
            "in": "path",
            "required": true,
            "description": "Your own id for the user, as you named them.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "domain",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 253,
              "pattern": "^[a-z0-9.-]+$",
              "description": "The site, a bare host name on the deployment's browser.allowed_domains, such as `ixigo.com`. Cookies of its subdomains count too.",
              "examples": [
                "ixigo.com"
              ]
            }
          },
          {
            "name": "names",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_.-]{1,64}(,[A-Za-z0-9_.-]{1,64}){0,9}$",
              "description": "The cookie names to look for, comma-separated, up to 10.",
              "examples": [
                "at,lt"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "cookies": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "name": {
                            "type": "string",
                            "description": "The cookie's name, one of those asked for."
                          },
                          "domain": {
                            "type": "string",
                            "description": "The host the cookie is set for, with no leading dot."
                          },
                          "expires_at": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "When it expires, as an ISO 8601 time; null for a cookie that lasts only while the browser runs."
                          }
                        },
                        "required": [
                          "name",
                          "domain",
                          "expires_at"
                        ]
                      },
                      "description": "The cookies of those names the browser holds for the site and its subdomains. Never a value. Empty when it holds none."
                    },
                    "woke": {
                      "type": "boolean",
                      "description": "true when the computer was asleep and this call woke it."
                    }
                  },
                  "required": [
                    "cookies",
                    "woke"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/users/{user_id}/browser/watch": {
      "get": {
        "operationId": "getUsersByUserIdBrowserWatch",
        "summary": "Watch the browser fetch's tabs live, as text/event-stream. Read only: allowed sites only, a tab on a blocked path is hidden, and it never wakes the computer.",
        "tags": [
          "Computer setup"
        ],
        "x-vestra-line": "watch",
        "x-vestra-scope": "runtime",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "user_id",
            "in": "path",
            "required": true,
            "description": "Your own id for the user, as you named them.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "fps",
            "in": "query",
            "required": false,
            "schema": {
              "default": 6,
              "description": "Pictures a second, 1 to 10.",
              "type": "integer",
              "minimum": 1,
              "maximum": 10
            }
          },
          {
            "name": "width",
            "in": "query",
            "required": false,
            "schema": {
              "default": 960,
              "description": "Picture width, 320 to 1280.",
              "type": "integer",
              "minimum": 320,
              "maximum": 1280
            }
          },
          {
            "name": "Last-Event-ID",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Resume after this event id."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/event-stream": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/sessions/{session_id}/voice": {
      "post": {
        "operationId": "postSessionsBySessionIdVoice",
        "summary": "Called from the user's browser with the session's token and its WebRTC offer; answers the model's answer. Audio then flows straight to the voice model, and everything said lands in the session's conversation. For a session opened with voice.",
        "tags": [
          "Sessions"
        ],
        "x-vestra-line": "talk",
        "security": [
          {
            "clientToken": []
          }
        ],
        "parameters": [
          {
            "name": "session_id",
            "in": "path",
            "required": true,
            "description": "The session's id (`ses_...`).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "type": "string",
                      "const": "session_voice",
                      "description": "Always session_voice."
                    },
                    "sdp": {
                      "type": "string",
                      "description": "The answer to the browser's offer (its SDP): hand it to the browser's connection."
                    },
                    "voice": {
                      "type": "string",
                      "description": "The voice Bash speaks in."
                    }
                  },
                  "required": [
                    "object",
                    "sdp",
                    "voice"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "sdp": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 65536,
                    "description": "The browser's WebRTC offer (its SDP), in at most 65,536 characters."
                  }
                },
                "required": [
                  "sdp"
                ],
                "additionalProperties": false
              }
            }
          }
        }
      }
    },
    "/v1/mcp": {
      "post": {
        "operationId": "postMcp",
        "summary": "One MCP endpoint (streamable HTTP): the card's lines as tools, each with an optional user (with none, your company's own Bash). Keys and secrets stay with people.",
        "tags": [
          "MCP server"
        ],
        "x-vestra-line": "mcp",
        "x-vestra-scope": "runtime",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/a2a/{deployment_id}/.well-known/agent-card.json": {
      "get": {
        "operationId": "getA2aByDeploymentIdWellKnownAgentCardJson",
        "summary": "What this deployment does and how to authenticate, for other agents to discover.",
        "tags": [
          "A2A"
        ],
        "x-vestra-line": "mcp",
        "security": [],
        "parameters": [
          {
            "name": "deployment_id",
            "in": "path",
            "required": true,
            "description": "The deployment's id (`dep_...`). The /v1/deployments routes also take its name.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "name": {
                      "type": "string",
                      "minLength": 1,
                      "description": "The deployment's name."
                    },
                    "description": {
                      "type": "string",
                      "minLength": 1,
                      "description": "The deployment's description, then how to talk to Bash."
                    },
                    "supportedInterfaces": {
                      "minItems": 1,
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "url": {
                            "type": "string",
                            "format": "uri",
                            "description": "The deployment's A2A address."
                          },
                          "protocolBinding": {
                            "type": "string",
                            "description": "How to call it: JSONRPC."
                          },
                          "protocolVersion": {
                            "type": "string",
                            "description": "The A2A version it speaks.",
                            "examples": [
                              "1.0"
                            ]
                          }
                        },
                        "required": [
                          "url",
                          "protocolBinding",
                          "protocolVersion"
                        ]
                      },
                      "description": "Where and how to call it."
                    },
                    "provider": {
                      "description": "Who runs the agent.",
                      "type": "object",
                      "properties": {
                        "url": {
                          "type": "string",
                          "format": "uri",
                          "description": "The provider's site."
                        },
                        "organization": {
                          "type": "string",
                          "description": "The provider's name: Vestra."
                        }
                      },
                      "required": [
                        "url",
                        "organization"
                      ]
                    },
                    "version": {
                      "type": "string",
                      "minLength": 1,
                      "description": "The deployment's live version, as a string."
                    },
                    "documentationUrl": {
                      "description": "Where its documentation is.",
                      "type": "string",
                      "format": "uri"
                    },
                    "capabilities": {
                      "type": "object",
                      "properties": {
                        "streaming": {
                          "description": "Whether it streams: true.",
                          "type": "boolean"
                        },
                        "pushNotifications": {
                          "description": "Whether it sends push notifications: false, use a webhook endpoint instead.",
                          "type": "boolean"
                        },
                        "extendedAgentCard": {
                          "description": "Whether it has an extended card: false.",
                          "type": "boolean"
                        }
                      },
                      "description": "What it can do."
                    },
                    "securitySchemes": {
                      "description": "How a caller proves who it is, by name.",
                      "type": "object",
                      "propertyNames": {
                        "type": "string"
                      },
                      "additionalProperties": {
                        "type": "object",
                        "properties": {
                          "httpAuthSecurityScheme": {
                            "type": "object",
                            "properties": {
                              "scheme": {
                                "type": "string",
                                "description": "The HTTP scheme: Bearer."
                              },
                              "bearerFormat": {
                                "description": "What the token looks like: an API key of the company that owns the deployment.",
                                "type": "string"
                              },
                              "description": {
                                "description": "The scheme, in plain words.",
                                "type": "string"
                              }
                            },
                            "required": [
                              "scheme"
                            ],
                            "description": "An HTTP authorization scheme."
                          }
                        },
                        "required": [
                          "httpAuthSecurityScheme"
                        ]
                      }
                    },
                    "securityRequirements": {
                      "description": "Which schemes a call must use.",
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "schemes": {
                            "type": "object",
                            "propertyNames": {
                              "type": "string"
                            },
                            "additionalProperties": {
                              "type": "object",
                              "properties": {
                                "list": {
                                  "type": "array",
                                  "items": {
                                    "type": "string"
                                  },
                                  "description": "The scopes the scheme needs; empty for none."
                                }
                              },
                              "required": [
                                "list"
                              ]
                            },
                            "description": "The schemes a call needs, by name."
                          }
                        },
                        "required": [
                          "schemes"
                        ]
                      }
                    },
                    "defaultInputModes": {
                      "minItems": 1,
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "What it takes: text/plain and application/json."
                    },
                    "defaultOutputModes": {
                      "minItems": 1,
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "What it answers with: text/plain and application/json."
                    },
                    "skills": {
                      "minItems": 1,
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "The skill's id."
                          },
                          "name": {
                            "type": "string",
                            "description": "The skill's name."
                          },
                          "description": {
                            "type": "string",
                            "description": "What it does."
                          },
                          "tags": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            },
                            "description": "Words to find it by."
                          },
                          "examples": {
                            "description": "Requests it handles, as examples.",
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          },
                          "inputModes": {
                            "description": "What it takes.",
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          },
                          "outputModes": {
                            "description": "What it answers with.",
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        },
                        "required": [
                          "id",
                          "name",
                          "description",
                          "tags"
                        ]
                      },
                      "description": "What the agent offers: one skill, talking to Bash."
                    }
                  },
                  "required": [
                    "name",
                    "description",
                    "supportedInterfaces",
                    "version",
                    "capabilities",
                    "defaultInputModes",
                    "defaultOutputModes",
                    "skills"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/a2a/{deployment_id}": {
      "post": {
        "operationId": "postA2aByDeploymentId",
        "summary": "A2A JSON-RPC: send a message, stream, get, list or cancel. Push notifications are not offered; subscribe to webhooks instead. An A2A exchange is a conversation; an A2A task is its work.",
        "tags": [
          "A2A"
        ],
        "x-vestra-line": "mcp",
        "x-vestra-scope": "runtime",
        "security": [
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "deployment_id",
            "in": "path",
            "required": true,
            "description": "The deployment's id (`dep_...`). The /v1/deployments routes also take its name.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Vestra-User",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Your id for the user this call acts for."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/openapi.json": {
      "get": {
        "operationId": "getOpenapiJson",
        "summary": "The whole contract, machine-readable.",
        "tags": [
          "Contract"
        ],
        "x-vestra-line": "keys",
        "security": [],
        "parameters": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "ApiError": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "type": {
                "type": "string",
                "enum": [
                  "invalid_request",
                  "authentication",
                  "permission",
                  "not_found",
                  "conflict",
                  "rate_limited",
                  "cap_reached",
                  "upstream",
                  "internal"
                ],
                "description": "The kind of error, one per status: `invalid_request`, `authentication`, `permission`, `not_found`, `conflict`, `rate_limited`, `cap_reached`, `upstream` or `internal`."
              },
              "code": {
                "type": "string",
                "description": "What went wrong, exactly: branch on this. The errors reference lists every code, with what to do.",
                "examples": [
                  "user_not_found"
                ]
              },
              "message": {
                "type": "string",
                "description": "What went wrong, in a sentence a person can read. It may change: never branch on it."
              },
              "param": {
                "description": "The field the error is about, as a path such as `tools.0.input`; absent when it is about no one field.",
                "type": "string"
              },
              "names": {
                "description": "With `secret_missing`: the company secrets to store before applying the file again.",
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "deployments": {
                "description": "With `mcp_server_shared`: the other deployments that run the MCP server the file would change.",
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "partial": {
                "description": "With `timeout` on a browser fetch: what the page had sent before the time ran out.",
                "type": "object",
                "properties": {
                  "final_url": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "The page's address when the fetch ended, after any redirects and steps; null if it never opened."
                  },
                  "elapsed_ms": {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991,
                    "description": "How long the whole call took, in ms, waking included."
                  },
                  "woke": {
                    "type": "boolean",
                    "description": "true when the computer was asleep and this call woke it."
                  },
                  "timings": {
                    "type": "object",
                    "properties": {
                      "wake_ms": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991,
                        "description": "How long waking the computer took: 0 when it was up."
                      },
                      "nav_ms": {
                        "anyOf": [
                          {
                            "type": "integer",
                            "minimum": -9007199254740991,
                            "maximum": 9007199254740991
                          },
                          {
                            "type": "null"
                          }
                        ],
                        "description": "When the page started showing (its navigation committed); null if it never did, or when the fetch ran on a kept tab with nothing to open."
                      },
                      "first_capture_ms": {
                        "anyOf": [
                          {
                            "type": "integer",
                            "minimum": -9007199254740991,
                            "maximum": 9007199254740991
                          },
                          {
                            "type": "null"
                          }
                        ],
                        "description": "When the first kept response finished; null if none did."
                      },
                      "done_ms": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991,
                        "description": "When the computer finished the fetch."
                      }
                    },
                    "required": [
                      "wake_ms",
                      "nav_ms",
                      "first_capture_ms",
                      "done_ms"
                    ],
                    "description": "Where the time went, each in ms after the call arrived."
                  },
                  "captures": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "match": {
                          "type": "string",
                          "description": "The capture this response answers, or the page_fetch step's capture_as."
                        },
                        "url": {
                          "type": "string",
                          "description": "The full address of the response."
                        },
                        "status": {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991,
                          "description": "Its HTTP status."
                        },
                        "content_type": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ],
                          "description": "Its content type, such as application/json; null when it had none."
                        },
                        "body": {
                          "type": "string",
                          "description": "Its body, as text."
                        },
                        "truncated": {
                          "type": "boolean",
                          "description": "true when the body was longer than max_bytes, or the fetch had kept 8000000 bytes in all, and it was cut. With sse \"last\": true when the event kept is not the stream's last one (the last was too long, or the stream ended partway through it)."
                        },
                        "at_ms": {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991,
                          "description": "When it finished, in ms after the call arrived."
                        }
                      },
                      "required": [
                        "match",
                        "url",
                        "status",
                        "content_type",
                        "body",
                        "truncated",
                        "at_ms"
                      ]
                    },
                    "description": "Every response kept, in the order they finished."
                  },
                  "frames": {
                    "description": "With `frames` asked: the pictures, in the order they were taken. A frame that would have slowed the answer is left out.",
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "label": {
                          "type": "string",
                          "description": "Which moment: `navigated`, `captured <match>`, `after <step>` or `done`.",
                          "examples": [
                            "navigated"
                          ]
                        },
                        "at_ms": {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991,
                          "description": "When it was taken, in ms after the call arrived."
                        },
                        "page_url": {
                          "type": "string",
                          "description": "The page's address when it was taken; always on an allowed site."
                        },
                        "jpeg_base64": {
                          "type": "string",
                          "description": "The picture, a JPEG, as base64."
                        }
                      },
                      "required": [
                        "label",
                        "at_ms",
                        "page_url",
                        "jpeg_base64"
                      ]
                    }
                  },
                  "step": {
                    "description": "With a `timeout`: where the fetch was when the time ran out: `navigate`, a step by its number and op such as `2 scroll`, or `captures` when every step was done and it was waiting for the required captures.",
                    "examples": [
                      "2 scroll"
                    ],
                    "type": "string"
                  },
                  "challenge": {
                    "description": "`turnstile`: the page called Cloudflare's Turnstile check.",
                    "type": "string",
                    "const": "turnstile"
                  }
                },
                "required": [
                  "final_url",
                  "elapsed_ms",
                  "woke",
                  "timings",
                  "captures"
                ]
              },
              "retry_after_ms": {
                "description": "With `browser_busy`: how long to wait before trying again, in ms.",
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              "request_id": {
                "type": "string",
                "description": "This request's id: send it to Vestra when the error is on our side."
              }
            },
            "required": [
              "type",
              "code",
              "message",
              "request_id"
            ],
            "description": "The error."
          }
        },
        "required": [
          "error"
        ]
      }
    },
    "securitySchemes": {
      "apiKey": {
        "type": "http",
        "scheme": "bearer",
        "description": "Your API key: vk_live_ or vk_test_ followed by the secret."
      },
      "clientToken": {
        "type": "http",
        "scheme": "bearer",
        "description": "A session's short-lived token (POST /v1/sessions): it reaches one user, and only the session's conversation."
      }
    }
  },
  "x-vestra-errors": [
    {
      "code": "answer_mismatch",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "The answer's shape is not one this interaction takes.",
      "todo": "Send the body its type takes: an approval `approve`, a question `answers`, a call to your tool `output` or `error`."
    },
    {
      "code": "answers_mismatch",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "The answers do not match the questions.",
      "todo": "Send exactly one answer for each question, in the order they were asked."
    },
    {
      "code": "answers_not_expected",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "This interaction takes a yes or a no, not answers.",
      "todo": "Send `{ \"approve\": true }` or `{ \"approve\": false }`."
    },
    {
      "code": "answers_required",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "This question waits for answers.",
      "todo": "Send `answers`, one for each question, or `{ \"approve\": false }` to decline."
    },
    {
      "code": "app_not_connectable",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "This app cannot be connected yet.",
      "todo": "Pick another app from `GET /v1/apps`."
    },
    {
      "code": "auth_twice",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "An MCP tool in the file gives both `auth` and an Authorization header.",
      "todo": "Keep one of the two."
    },
    {
      "code": "binary_file",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "A skill holds a file that is not text.",
      "todo": "Skills take text files only: leave out images and other binaries."
    },
    {
      "code": "body_too_large",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "The request body, or a context inside it, is larger than this route takes.",
      "todo": "Send less, or upload the data as a file with `POST /v1/files` and name it."
    },
    {
      "code": "bundle_too_large",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "A skill is larger than 5 MB.",
      "todo": "Make the skill smaller: keep what Bash reads, and leave out the rest."
    },
    {
      "code": "cap_above_maximum",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "A cap is above what is allowed: the company cap above its ceiling, or a user cap above the company cap.",
      "todo": "Lower the cap, or ask Vestra to raise the ceiling."
    },
    {
      "code": "connect_app_instead",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "This interaction is an app to connect, and it is not answered with a body.",
      "todo": "Connect the app with `POST /v1/connections`: the interaction settles itself once the app is connected."
    },
    {
      "code": "conversation_required",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "The MCP tool needs a conversation and none was named.",
      "todo": "Name the conversation to act on."
    },
    {
      "code": "conversation_user_mismatch",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "The conversation belongs to a different user than the one named.",
      "todo": "Name the conversation of the same user, or leave the user out."
    },
    {
      "code": "decision_not_expected",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "A hand-off answer was sent to something that is not a hand-off, or the other way round.",
      "todo": "Send `done`, `could_not` or `not_now` to a hand-off only, and the body its type takes to the others."
    },
    {
      "code": "deployment_required",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "This call needs a deployment and none was named.",
      "todo": "Name the deployment by its name or its `dep_` id."
    },
    {
      "code": "describe_or_answer",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "The MCP `init` tool needs a description to start, or a deployment, a conversation and an answer to go on.",
      "todo": "Start with `describe`, then answer with `deployment`, `conversation` and `answer`."
    },
    {
      "code": "document_too_large",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "A notebook document is larger than 512 KB of text.",
      "todo": "Split it into several documents."
    },
    {
      "code": "duplicate_name",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "The file names two tools, tests or routines the same.",
      "todo": "Give each its own name."
    },
    {
      "code": "duplicate_path",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "Two files of a skill share one path.",
      "todo": "Give each file its own path."
    },
    {
      "code": "file_required",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "The upload has no file in it.",
      "todo": "Send the file as multipart/form-data, in a field named `file`."
    },
    {
      "code": "file_too_large",
      "status": [
        400,
        413
      ],
      "type": "invalid_request",
      "means": "A file is larger than its route takes: a file of a skill over 1 MB, or an upload over its limit.",
      "todo": "Send a smaller file."
    },
    {
      "code": "install_ability_instead",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "Bash asked to install an ability, and that is not approved through the API.",
      "todo": "Add the skill or MCP server to your deployment instead; this interaction can only be declined."
    },
    {
      "code": "invalid_conversation_id",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "`conversation_id` is not a conversation id.",
      "todo": "Send a `conv_` id, as the API gave it."
    },
    {
      "code": "invalid_cursor",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "The cursor is not one this API gave.",
      "todo": "Send the `next_cursor` of the page before, unchanged."
    },
    {
      "code": "invalid_deployment",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "That is not a deployment id or name.",
      "todo": "Send a `dep_` id, or the name, with an optional `@version`."
    },
    {
      "code": "invalid_deployment_id",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "`deployment_id` is not a deployment id.",
      "todo": "Send a `dep_` id, as the API gave it."
    },
    {
      "code": "invalid_filename",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "The file name is not one plain name.",
      "todo": "Use one name with no slashes or control characters, at most 255 bytes."
    },
    {
      "code": "invalid_frontmatter",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "A skill's SKILL.md frontmatter is not valid YAML.",
      "todo": "Fix the YAML between the two `---` lines at the top of SKILL.md."
    },
    {
      "code": "invalid_idempotency_key",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "The Idempotency-Key header is empty or too long.",
      "todo": "Send 1 to 255 characters."
    },
    {
      "code": "invalid_json",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "The request body is not valid JSON.",
      "todo": "Send JSON, with `Content-Type: application/json`."
    },
    {
      "code": "invalid_language",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "That is not a language tag.",
      "todo": "Use `auto`, or a tag such as `en`, `hi` or `pt-BR`."
    },
    {
      "code": "invalid_last_event_id",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "`Last-Event-ID` or `after` is not a whole number.",
      "todo": "Send the `seq` of the last event you saw, or 0 for the start."
    },
    {
      "code": "invalid_limit",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "`limit` is not a whole number from 1 to 100.",
      "todo": "Send a `limit` from 1 to 100, or leave it out."
    },
    {
      "code": "invalid_manifest",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "The deployment's settings do not fit together: the message and `param` say where.",
      "todo": "Fix the field `param` names and send it again."
    },
    {
      "code": "invalid_memory",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "The memory is not one Bash can keep.",
      "todo": "Send `text` of 1 to 1,000 characters, and optionally a `kind`: identity, relationship, commitment, preference, project_state or other."
    },
    {
      "code": "invalid_mode",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "The `Vestra-Mode` header is not live or test.",
      "todo": "Send `live` or `test`."
    },
    {
      "code": "invalid_org_header",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "The `Vestra-Org` header is not an org id.",
      "todo": "Send your org id, like `org_...`."
    },
    {
      "code": "invalid_origin",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "An allowed origin is not an https origin.",
      "todo": "Write it as `https://app.example.com`, with no path."
    },
    {
      "code": "invalid_query",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "A query field is not valid: `param` names it.",
      "todo": "Fix that field, or leave it out."
    },
    {
      "code": "invalid_repo",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "A repository in the file is not an address Bash can clone.",
      "todo": "Write `github.com/owner/repo`, or its https URL."
    },
    {
      "code": "invalid_request",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "The request is not valid: the message and `param` say which field and why.",
      "todo": "Fix that field and send it again. The route says what each field takes."
    },
    {
      "code": "invalid_schedule",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "The schedule is not one a routine can keep: an unknown time zone, or a cron that does not read.",
      "todo": "Use an IANA time zone such as `Asia/Kolkata`, and a cron such as `0 7 * * *`, or write `every` in plain words."
    },
    {
      "code": "invalid_secret_name",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "That is not a secret name.",
      "todo": "Use capitals, digits and underscores, starting with a capital: `PNR_API_KEY`."
    },
    {
      "code": "invalid_skill",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "A skill's SKILL.md does not meet the skill format.",
      "todo": "Fix what the message names, and upload the skill again."
    },
    {
      "code": "invalid_task_id",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "`task_id` is not a task id.",
      "todo": "Send a `task_` id, as the API gave it."
    },
    {
      "code": "invalid_tool_input",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "A function tool's `input` is neither shorthand nor JSON Schema.",
      "todo": "Write each argument as a type such as `string` or `integer?`, or give JSON Schema with `type: object`."
    },
    {
      "code": "invalid_trigger",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "A routine's `filters` are not ones it can match.",
      "todo": "Fix the filter the message names."
    },
    {
      "code": "invalid_user_timezone",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "The user's own time zone is not an IANA name, so `every` cannot be read in it.",
      "todo": "Send `timezone`, or fix the user with `PATCH /v1/users/{user_id}`."
    },
    {
      "code": "invalid_window",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "`from` is after `to`, or one of them is not a date.",
      "todo": "Send dates like `2026-10-01`, with `from` on or before `to`."
    },
    {
      "code": "invalid_zip",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "The skill upload is not a zip archive that reads.",
      "todo": "Zip the skill folder again and upload it."
    },
    {
      "code": "mcp_server_not_listed",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "A tool policy names an MCP server the version does not list.",
      "todo": "Add the server to `mcp_servers`, or drop its policy."
    },
    {
      "code": "memory_endpoint_required",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "Memory kept on your side needs an endpoint for Bash to ask.",
      "todo": "Send `memory_endpoint` with `memory_mode: customer`."
    },
    {
      "code": "message_required",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "There is nothing to send: no message, attachment or tool result.",
      "todo": "Send a `message`, an attachment or tool results."
    },
    {
      "code": "multipart_required",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "The upload is not multipart/form-data.",
      "todo": "Send the file as multipart/form-data, in a field named `file`."
    },
    {
      "code": "name_mismatch",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "The file's `name` and the name in the path differ.",
      "todo": "Make them the same."
    },
    {
      "code": "no_output_schema",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "This work was not asked for structured output, so it has no result to read.",
      "todo": "Ask with `output_schema` when you want a result to read."
    },
    {
      "code": "nonce_mismatch",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "An approval that moves money or acts for the user needs its nonce, and it was missing or wrong.",
      "todo": "Read the interaction and send its `nonce` with `approve: true`."
    },
    {
      "code": "not_a_schedule_routine",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "This routine runs on a call, so it has no schedule to change.",
      "todo": "Change its filters, or make a new routine that runs on a schedule."
    },
    {
      "code": "not_a_trigger_routine",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "This routine runs on a schedule, so it takes no payload and has no filters.",
      "todo": "Run it with `POST /v1/routines/{routine_id}/run`."
    },
    {
      "code": "notebook_full",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "The notebook is full: too many documents, or more than 5 MB of text.",
      "todo": "Delete documents, or start another notebook."
    },
    {
      "code": "oauth_not_available",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "OAuth for company MCP servers is not available yet.",
      "todo": "Send headers with `${user_secret:NAME}` for each user's own credentials."
    },
    {
      "code": "output_schema_invalid",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "`output_schema` is not a schema Bash can follow.",
      "todo": "Send a JSON Schema object; the message says what is wrong with it."
    },
    {
      "code": "output_schema_too_large",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "`output_schema` is larger than 32 KB.",
      "todo": "Send a smaller schema."
    },
    {
      "code": "path_not_resolved",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "The file names a folder or file on your computer, and HTTP cannot read it.",
      "todo": "Deploy with the CLI or an SDK: they upload it and send what it became."
    },
    {
      "code": "payload_too_large",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "A routine's trigger payload is larger than 4 KB.",
      "todo": "Send less, or put the data in a file and name it."
    },
    {
      "code": "present_user_required",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "This approval moves money or acts for the user, and the user must be there to say yes.",
      "todo": "Approve it only while the user is in your app, and send `present_user: true`."
    },
    {
      "code": "query_required",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "A memory search needs a question.",
      "todo": "Send `q`, 1 to 500 characters."
    },
    {
      "code": "raw_secret_in_header",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "An MCP header holds a raw credential.",
      "todo": "Store it with `PUT /v1/secrets/{name}` and write `${secret:NAME}` in the header."
    },
    {
      "code": "return_url_not_allowed",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "`return_url` is not one of your allowed return URLs.",
      "todo": "Add it with `PATCH /v1/org`, or send one that is allowed."
    },
    {
      "code": "schedule_too_frequent",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "A routine runs at most once every 15 minutes.",
      "todo": "Choose a schedule that runs less often."
    },
    {
      "code": "schedule_unreadable",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "`every` does not read as a schedule.",
      "todo": "Write it like `weekday at 08:00`, `mon, wed, fri at 18:30` or `30 minutes`."
    },
    {
      "code": "sdp_required",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "A voice call needs the browser's WebRTC offer.",
      "todo": "Send the offer as `sdp`."
    },
    {
      "code": "secret_in_url",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "An MCP server's URL carries a credential.",
      "todo": "Move it into a header as `${secret:NAME}`."
    },
    {
      "code": "secret_missing",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "The file names company secrets that are not stored for this mode: `names` lists them.",
      "todo": "Store each with `PUT /v1/secrets/{name}` and a key of this mode, then apply the file again."
    },
    {
      "code": "skill_md_missing",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "A skill folder has no SKILL.md at its top.",
      "todo": "Add SKILL.md at the top of the folder."
    },
    {
      "code": "skill_name_changed",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "A new version of a skill changes the name in its SKILL.md.",
      "todo": "Keep the name, or upload a new skill to rename it."
    },
    {
      "code": "skill_name_required",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "A skill's SKILL.md has no name.",
      "todo": "Give the frontmatter a `name` that starts with a letter."
    },
    {
      "code": "title_required",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "A raw text upload to a notebook needs a title.",
      "todo": "Send `?title=`."
    },
    {
      "code": "too_many_files",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "A skill holds more files than it may.",
      "todo": "Keep the files Bash reads, and leave out the rest."
    },
    {
      "code": "too_many_headers",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "An MCP server sends more than 20 headers.",
      "todo": "Send at most 20."
    },
    {
      "code": "tool_listed_twice",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "A tool is in more than one of an MCP server's lists.",
      "todo": "Put each tool in one list: `deny`, `require_approval` or `run_without_asking`."
    },
    {
      "code": "tool_not_on_server",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "An MCP server's `run_without_asking` names a tool the server does not list.",
      "todo": "Use each name exactly as the server lists it (`GET /v1/mcp-servers/{server_id}/tools`), or drop it."
    },
    {
      "code": "tool_name_reserved",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "A tool, or an MCP server's slug, takes a name Bash already uses for one of its own tools or tool servers.",
      "todo": "Name it something else."
    },
    {
      "code": "tool_not_declared",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "A test gives results for a tool the file does not declare.",
      "todo": "Declare the tool in `tools`, or drop its results from the test's `tool_results`."
    },
    {
      "code": "tool_policy_twice",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "Two tool policies name the same MCP server.",
      "todo": "Give each MCP server one policy."
    },
    {
      "code": "tool_schema_invalid",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "A tool's input schema is not a JSON Schema object.",
      "todo": "Give it `type: object` and its `properties`."
    },
    {
      "code": "unknown_model",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "That is not a model a deployment can use.",
      "todo": "Use `default`, or an id from `GET /v1/models`."
    },
    {
      "code": "unsafe_path",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "A file of a skill has a path that is not allowed.",
      "todo": "Use plain relative paths, with no `..` and no leading slash."
    },
    {
      "code": "unsupported_kind",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "This kind of interaction cannot be answered, or withdrawn, through the API.",
      "todo": "Decline it, or let the user choose in Vestra."
    },
    {
      "code": "url_not_public",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "The URL is not a public https address.",
      "todo": "Use an https URL that reaches the public internet."
    },
    {
      "code": "user_must_connect",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "The user signs in to this app themselves.",
      "todo": "Send the user the connect link. Through the API, this interaction can only be declined."
    },
    {
      "code": "user_required",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "This company asks for a user on every request, and none was named.",
      "todo": "Name the user, or turn off `require_user` with `PATCH /v1/org`."
    },
    {
      "code": "version_not_allowed",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "This call runs the current version, so it takes no `@version`.",
      "todo": "Drop the `@version`."
    },
    {
      "code": "voice_unknown",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "That is not one of the voices.",
      "todo": "Use one of the voices the message lists."
    },
    {
      "code": "window_too_long",
      "status": [
        400
      ],
      "type": "invalid_request",
      "means": "The usage window is longer than the API reads at once.",
      "todo": "Ask for a shorter window, and page through it."
    },
    {
      "code": "invalid_api_key",
      "status": [
        401
      ],
      "type": "authentication",
      "means": "That API key is not valid.",
      "todo": "Send a key from the console, as `Authorization: Bearer vk_test_...`."
    },
    {
      "code": "invalid_session",
      "status": [
        401
      ],
      "type": "authentication",
      "means": "The console session is not valid.",
      "todo": "Sign in again."
    },
    {
      "code": "key_expired",
      "status": [
        401
      ],
      "type": "authentication",
      "means": "This API key has expired.",
      "todo": "Use the key that replaced it."
    },
    {
      "code": "key_revoked",
      "status": [
        401,
        409
      ],
      "type": "authentication",
      "means": "This API key was revoked: it calls nothing, and it cannot be rolled.",
      "todo": "Make a new key in the console or with `POST /v1/keys`."
    },
    {
      "code": "missing_api_key",
      "status": [
        401
      ],
      "type": "authentication",
      "means": "The request has no API key.",
      "todo": "Send `Authorization: Bearer vk_test_...` (or `vk_live_...`)."
    },
    {
      "code": "missing_session",
      "status": [
        401
      ],
      "type": "authentication",
      "means": "The console request has no session.",
      "todo": "Send your Vestra session as `Bearer <token>`."
    },
    {
      "code": "org_header_required",
      "status": [
        401
      ],
      "type": "authentication",
      "means": "A console session must say which company it acts for.",
      "todo": "Send the `Vestra-Org` header with your org id."
    },
    {
      "code": "session_ended",
      "status": [
        401
      ],
      "type": "authentication",
      "means": "This session has ended, and its token stopped working.",
      "todo": "Ask your server for a new session with `POST /v1/sessions`."
    },
    {
      "code": "org_cap_reached",
      "status": [
        402
      ],
      "type": "cap_reached",
      "means": "The company's spending cap is reached: its cap for the day (it resets at midnight UTC) or for the month (it resets on the 1st, UTC).",
      "todo": "`GET /v1/limits` says which. Raise it with `PATCH /v1/limits`, or wait for it to reset."
    },
    {
      "code": "spend_cap_reached",
      "status": [
        402
      ],
      "type": "cap_reached",
      "means": "A spending cap is reached, the user's or the company's, for the day or the month, so their computer was not woken, or the voice call did not open.",
      "todo": "`GET /v1/users/{user_id}` and `GET /v1/limits` say which. Raise it, or wait for it to reset: a day's cap at midnight UTC, a month's on the 1st."
    },
    {
      "code": "storage_quota_exceeded",
      "status": [
        402
      ],
      "type": "cap_reached",
      "means": "This user has used all of their file storage.",
      "todo": "Delete files with `DELETE /v1/files/{file_id}` to make room."
    },
    {
      "code": "user_cap_reached",
      "status": [
        402
      ],
      "type": "cap_reached",
      "means": "This user's spending cap is reached: their cap for the day (it resets at midnight UTC) or for the month (it resets on the 1st, UTC).",
      "todo": "`GET /v1/users/{user_id}` says what they may still spend. Raise their cap with `PATCH /v1/users/{user_id}`, or wait for it to reset."
    },
    {
      "code": "wallet_empty",
      "status": [
        402
      ],
      "type": "cap_reached",
      "means": "The wallet for this mode is empty.",
      "todo": "Add credits in the console, then retry."
    },
    {
      "code": "account_blocked",
      "status": [
        403
      ],
      "type": "permission",
      "means": "This account or user is blocked.",
      "todo": "Contact Vestra support."
    },
    {
      "code": "app_not_allowed",
      "status": [
        403
      ],
      "type": "permission",
      "means": "This app is not on the deployment's list of apps.",
      "todo": "Add it to the deployment's `apps`, or pick an app that is there."
    },
    {
      "code": "client_token_not_allowed",
      "status": [
        403
      ],
      "type": "permission",
      "means": "A session's token cannot call this route.",
      "todo": "Call it from your server, with an API key."
    },
    {
      "code": "domain_not_allowed",
      "status": [
        403
      ],
      "type": "permission",
      "means": "The page is on a site the user's deployment does not list in `browser.allowed_domains`, or a browser fetch's page went to one.",
      "todo": "Add the site to the deployment's `browser.allowed_domains`, or open a page on a site that is there."
    },
    {
      "code": "email_required",
      "status": [
        403
      ],
      "type": "permission",
      "means": "The signed-in Vestra account has no email address, and a company account is made for an email.",
      "todo": "Sign in with an account that has an email address, or contact Vestra support."
    },
    {
      "code": "insufficient_role",
      "status": [
        403
      ],
      "type": "permission",
      "means": "This caller cannot do this: a console member without the role, or a session token.",
      "todo": "Ask an owner or admin, or call it with an API key."
    },
    {
      "code": "live_mode_required",
      "status": [
        403
      ],
      "type": "permission",
      "means": "Only a live key changes what live users run.",
      "todo": "Use a live key, or the console in live mode."
    },
    {
      "code": "not_an_org_member",
      "status": [
        403
      ],
      "type": "permission",
      "means": "You are not a member of this company account.",
      "todo": "Ask an owner to invite you, or choose a company you belong to."
    },
    {
      "code": "not_interview_computer",
      "status": [
        403
      ],
      "type": "permission",
      "means": "Only the deployment's own interview can save its draft.",
      "todo": "Let the interview finish; it saves the draft itself."
    },
    {
      "code": "org_disabled",
      "status": [
        403
      ],
      "type": "permission",
      "means": "This company account is switched off.",
      "todo": "Contact Vestra support."
    },
    {
      "code": "origin_not_allowed",
      "status": [
        403
      ],
      "type": "permission",
      "means": "This page is not an allowed origin for this company.",
      "todo": "Add the origin to `allowed_embed_origins` with `PATCH /v1/org`."
    },
    {
      "code": "page_blocked",
      "status": [
        403
      ],
      "type": "permission",
      "means": "The page is on the deployment's `browser.blocked_paths`, such as a payment page, so the browser does not open it or act on it.",
      "todo": "Leave payments to the person, on their own device. Change `browser.blocked_paths` on the deployment only if this page should be open to the browser."
    },
    {
      "code": "sandbox_token_required",
      "status": [
        403
      ],
      "type": "permission",
      "means": "Only the interview computer can post this result.",
      "todo": "Nothing to do: this route is for Bash itself."
    },
    {
      "code": "scope_escalation",
      "status": [
        403
      ],
      "type": "permission",
      "means": "A key cannot give a scope it does not have.",
      "todo": "Make the new key with a key that has the scopes, or ask for fewer."
    },
    {
      "code": "scope_missing",
      "status": [
        403
      ],
      "type": "permission",
      "means": "This key's scopes do not reach this route.",
      "todo": "Make a key with the scope the message names, in the console or with `POST /v1/keys`."
    },
    {
      "code": "staff_only",
      "status": [
        403
      ],
      "type": "permission",
      "means": "This route is for Vestra staff.",
      "todo": "Nothing to do: it is not part of the API you call."
    },
    {
      "code": "test_mode_required",
      "status": [
        403
      ],
      "type": "permission",
      "means": "Only a test key does this: interviews, and changes to what test users run.",
      "todo": "Use a test key, or the console in test mode."
    },
    {
      "code": "user_disabled",
      "status": [
        403
      ],
      "type": "permission",
      "means": "This user is switched off.",
      "todo": "Turn them back on with `PATCH /v1/users/{user_id}`."
    },
    {
      "code": "view_only",
      "status": [
        403
      ],
      "type": "permission",
      "means": "This session can watch the screen but not drive it.",
      "todo": "Open the session with `screen: \"control\"` to take the wheel."
    },
    {
      "code": "batch_not_found",
      "status": [
        404
      ],
      "type": "not_found",
      "means": "No batch by that id, for this key's company and mode.",
      "todo": "Check the id, and that the key is of the mode the thing was made in: a test key never sees live data."
    },
    {
      "code": "connection_not_found",
      "status": [
        404
      ],
      "type": "not_found",
      "means": "No connected app by that id, for this key's company and mode.",
      "todo": "Check the id, and the user it belongs to: list them with `GET /v1/connections`."
    },
    {
      "code": "conversation_not_found",
      "status": [
        404
      ],
      "type": "not_found",
      "means": "No conversation by that id, for this key's company and mode.",
      "todo": "Check the id and the key's mode. A session token reaches only its own conversation."
    },
    {
      "code": "delivery_not_found",
      "status": [
        404
      ],
      "type": "not_found",
      "means": "No webhook delivery by that id, for this key's company and mode.",
      "todo": "List the deliveries with `GET /v1/webhooks/{endpoint_id}/deliveries`."
    },
    {
      "code": "deployment_not_found",
      "status": [
        404,
        400
      ],
      "type": "not_found",
      "means": "No deployment by that id, for this key's company and mode.",
      "todo": "Check the name or `dep_` id. Inside a file or a batch, it answers 400 on the field that names it."
    },
    {
      "code": "deployment_version_not_found",
      "status": [
        404
      ],
      "type": "not_found",
      "means": "No deployment version by that id, for this key's company and mode.",
      "todo": "List the versions with `GET /v1/deployments/{deployment_id}/versions`."
    },
    {
      "code": "document_not_found",
      "status": [
        404
      ],
      "type": "not_found",
      "means": "No notebook document by that id, for this key's company and mode.",
      "todo": "List the documents with `GET /v1/notebooks/{notebook_id}/documents`."
    },
    {
      "code": "event_not_found",
      "status": [
        404
      ],
      "type": "not_found",
      "means": "No event by that id, for this key's company and mode.",
      "todo": "List the recent ones with `GET /v1/events`."
    },
    {
      "code": "file_not_found",
      "status": [
        404,
        400
      ],
      "type": "not_found",
      "means": "No file by that id, for this key's company and mode.",
      "todo": "Check the id. A file attached to a message answers 400 on that field."
    },
    {
      "code": "interaction_not_found",
      "status": [
        404
      ],
      "type": "not_found",
      "means": "No interaction by that id, for this key's company and mode.",
      "todo": "List what Bash waits on with `GET /v1/interactions`. A session token reaches only its own."
    },
    {
      "code": "key_not_found",
      "status": [
        404
      ],
      "type": "not_found",
      "means": "No API key by that id, for this key's company and mode.",
      "todo": "List the keys with `GET /v1/keys`."
    },
    {
      "code": "mcp_server_not_found",
      "status": [
        404,
        400
      ],
      "type": "not_found",
      "means": "No MCP server by that id, for this key's company and mode.",
      "todo": "List them with `GET /v1/mcp-servers`. Inside a version, it answers 400 on the field."
    },
    {
      "code": "memory_not_found",
      "status": [
        404
      ],
      "type": "not_found",
      "means": "No memory by that id, for this key's company and mode.",
      "todo": "List what Bash remembers with `GET /v1/memory`."
    },
    {
      "code": "notebook_not_found",
      "status": [
        404,
        400
      ],
      "type": "not_found",
      "means": "No notebook by that id, for this key's company and mode.",
      "todo": "List them with `GET /v1/notebooks`. Inside a version, it answers 400 on the field."
    },
    {
      "code": "org_not_found",
      "status": [
        404
      ],
      "type": "not_found",
      "means": "The company account behind this call was not found.",
      "todo": "Contact Vestra support."
    },
    {
      "code": "routine_not_found",
      "status": [
        404
      ],
      "type": "not_found",
      "means": "No routine by that id, for this key's company and mode.",
      "todo": "List them with `GET /v1/routines`."
    },
    {
      "code": "route_not_found",
      "status": [
        404
      ],
      "type": "not_found",
      "means": "No route has that method and path.",
      "todo": "Check the path against the API reference, and that it starts `/v1/`."
    },
    {
      "code": "secret_not_found",
      "status": [
        404
      ],
      "type": "not_found",
      "means": "No secret by that name, for this mode and user.",
      "todo": "List the names with `GET /v1/secrets`."
    },
    {
      "code": "scenario_not_found",
      "status": [
        404
      ],
      "type": "not_found",
      "means": "No test scenario by that id, for this key's company and mode.",
      "todo": "List them with `GET /v1/deployments/{deployment_id}/scenarios`."
    },
    {
      "code": "session_not_found",
      "status": [
        404
      ],
      "type": "not_found",
      "means": "No session by that id, for this key's company and mode.",
      "todo": "Check the id. A session ends when its token does."
    },
    {
      "code": "skill_not_found",
      "status": [
        404,
        400
      ],
      "type": "not_found",
      "means": "No skill by that id, for this key's company and mode.",
      "todo": "List them with `GET /v1/skills`. Inside a file or a version, it answers 400 on the field."
    },
    {
      "code": "task_not_found",
      "status": [
        404
      ],
      "type": "not_found",
      "means": "No task by that id, for this key's company and mode.",
      "todo": "List the work with `GET /v1/tasks`."
    },
    {
      "code": "test_run_not_found",
      "status": [
        404
      ],
      "type": "not_found",
      "means": "No test run by that id, for this key's company and mode.",
      "todo": "List them with `GET /v1/deployments/{deployment_id}/test-runs`."
    },
    {
      "code": "tool_call_not_found",
      "status": [
        404
      ],
      "type": "not_found",
      "means": "No call to your tool by that id, for this key's company and mode.",
      "todo": "Answer the id the interaction gave you."
    },
    {
      "code": "turn_not_found",
      "status": [
        404
      ],
      "type": "not_found",
      "means": "No turn by that id, for this key's company and mode.",
      "todo": "Check the conversation and the turn id."
    },
    {
      "code": "user_not_found",
      "status": [
        404,
        400
      ],
      "type": "not_found",
      "means": "No user by that id, for this key's company and mode.",
      "todo": "Users are made the first time you act for them, or with `POST /v1/users`. Reads never make one."
    },
    {
      "code": "webhook_endpoint_not_found",
      "status": [
        404
      ],
      "type": "not_found",
      "means": "No webhook endpoint by that id, for this key's company and mode.",
      "todo": "List them with `GET /v1/webhooks`."
    },
    {
      "code": "method_not_allowed",
      "status": [
        405
      ],
      "type": "invalid_request",
      "means": "The MCP endpoint takes POST only.",
      "todo": "Send JSON-RPC to `POST /v1/mcp`."
    },
    {
      "code": "already_a_member",
      "status": [
        409
      ],
      "type": "conflict",
      "means": "You already belong to a company account, or this email already made one: a person makes only one of their own.",
      "todo": "Open the developer console to use it. To join another, or if yours is gone, ask Vestra to add you."
    },
    {
      "code": "batch_not_running",
      "status": [
        409
      ],
      "type": "conflict",
      "means": "That batch has already finished.",
      "todo": "Read its items with `GET /v1/batches/{batch_id}/items`."
    },
    {
      "code": "browser_busy",
      "status": [
        409
      ],
      "type": "conflict",
      "means": "The user's browser is already running four browser fetches.",
      "todo": "Retry after `retry_after_ms`, about a second, or run them one after another."
    },
    {
      "code": "browser_in_use",
      "status": [
        409
      ],
      "type": "conflict",
      "means": "A person is using this browser right now, so a browser fetch yields to them.",
      "todo": "Retry in a few seconds, when they are done."
    },
    {
      "code": "browser_not_open",
      "status": [
        409
      ],
      "type": "conflict",
      "means": "Bash's browser is not open right now.",
      "todo": "Ask Bash for work that opens its browser, then try again."
    },
    {
      "code": "payment_in_progress",
      "status": [
        409
      ],
      "type": "conflict",
      "means": "The person is paying for something in their browser right now; screenshots and the screen are paused until the payment ends.",
      "todo": "Try again in a minute."
    },
    {
      "code": "call_not_open",
      "status": [
        409
      ],
      "type": "conflict",
      "means": "The call ended before its line opened.",
      "todo": "Start the call again."
    },
    {
      "code": "conversation_busy",
      "status": [
        409
      ],
      "type": "conflict",
      "means": "Bash is still replying in this conversation.",
      "todo": "Wait for the reply, or stop it with `POST /v1/conversations/{conversation_id}/stop`."
    },
    {
      "code": "delivery_in_flight",
      "status": [
        409
      ],
      "type": "conflict",
      "means": "This delivery is being sent right now.",
      "todo": "Try again in a minute."
    },
    {
      "code": "deployment_archived",
      "status": [
        409
      ],
      "type": "conflict",
      "means": "This deployment is archived.",
      "todo": "Unarchive it with `PATCH /v1/deployments/{deployment_id}` first."
    },
    {
      "code": "deployment_busy",
      "status": [
        409
      ],
      "type": "conflict",
      "means": "Several versions were saved at once.",
      "todo": "Try again."
    },
    {
      "code": "deployment_changed",
      "status": [
        409
      ],
      "type": "conflict",
      "means": "The deployment changed while this ran.",
      "todo": "Read the deployment again, then retry."
    },
    {
      "code": "deployment_is_default",
      "status": [
        409
      ],
      "type": "conflict",
      "means": "This deployment is a default, for the company or for users, so it cannot be archived.",
      "todo": "Set another default with `PATCH /v1/org` or `PATCH /v1/users/{user_id}`, then archive it."
    },
    {
      "code": "deployment_not_live",
      "status": [
        409
      ],
      "type": "conflict",
      "means": "This deployment has no live version yet.",
      "todo": "Promote a version first, or call it with a test key."
    },
    {
      "code": "idempotency_in_progress",
      "status": [
        409
      ],
      "type": "conflict",
      "means": "A request with this Idempotency-Key is still running.",
      "todo": "Retry in a moment: you get its answer."
    },
    {
      "code": "idempotency_key_reused",
      "status": [
        409
      ],
      "type": "conflict",
      "means": "This Idempotency-Key was used for a different request.",
      "todo": "Use a new key for a new request."
    },
    {
      "code": "interaction_already_settled",
      "status": [
        409
      ],
      "type": "conflict",
      "means": "This interaction was already answered or withdrawn.",
      "todo": "Nothing to do: read it to see how it settled."
    },
    {
      "code": "limits_changed",
      "status": [
        409
      ],
      "type": "conflict",
      "means": "The limits changed while you saved.",
      "todo": "Read them with `GET /v1/limits` and retry."
    },
    {
      "code": "mcp_server_exists",
      "status": [
        409
      ],
      "type": "conflict",
      "means": "An MCP server with this slug already exists.",
      "todo": "Use the one there, or give a new slug."
    },
    {
      "code": "mcp_server_live",
      "status": [
        409
      ],
      "type": "conflict",
      "means": "A live deployment uses this MCP server.",
      "todo": "Change it with a live key, or as an owner or admin."
    },
    {
      "code": "mcp_server_shared",
      "status": [
        409
      ],
      "type": "conflict",
      "means": "Another deployment runs this MCP server, and the file would change its settings: `deployments` names them.",
      "todo": "Use the same headers in every file that names the server, or give this deployment its own server's URL."
    },
    {
      "code": "memory_not_kept",
      "status": [
        409
      ],
      "type": "conflict",
      "means": "This company keeps memory on its own side, so Bash holds none here.",
      "todo": "Read the memory from your own store."
    },
    {
      "code": "memory_off",
      "status": [
        409
      ],
      "type": "conflict",
      "means": "Memory is off for this company.",
      "todo": "Turn it on with `PATCH /v1/org` and a `memory_mode`."
    },
    {
      "code": "memory_panel_off",
      "status": [
        409
      ],
      "type": "conflict",
      "means": "Showing a user what Bash remembers is off for this company.",
      "todo": "Turn it on with `PATCH /v1/org` and `memory_panel: true`."
    },
    {
      "code": "not_a_company_user",
      "status": [
        409
      ],
      "type": "conflict",
      "means": "This user cannot be erased through the API.",
      "todo": "Contact Vestra support."
    },
    {
      "code": "notebook_busy",
      "status": [
        409
      ],
      "type": "conflict",
      "means": "The notebook changed while this call ran.",
      "todo": "Retry it."
    },
    {
      "code": "notebook_exists",
      "status": [
        409
      ],
      "type": "conflict",
      "means": "A notebook with this slug already exists.",
      "todo": "Use the one there, or give a new slug."
    },
    {
      "code": "no_open_tab",
      "status": [
        409
      ],
      "type": "conflict",
      "means": "A browser fetch with no url runs on the tab an earlier fetch kept open under its `tab` name, and none is kept under it now.",
      "todo": "Send url, with keep_open_ms to keep its tab for the next fetch."
    },
    {
      "code": "no_scenarios",
      "status": [
        409
      ],
      "type": "conflict",
      "means": "This deployment has no tests yet, so there is nothing to run.",
      "todo": "Add `tests` to vestra.yaml (or draft some with `POST /v1/deployments/{deployment_id}/scenarios/generate`), deploy, then run them."
    },
    {
      "code": "nothing_to_roll_back",
      "status": [
        409
      ],
      "type": "conflict",
      "means": "There is no earlier live version to go back to.",
      "todo": "Promote the version you want instead."
    },
    {
      "code": "org_routine_limit_reached",
      "status": [
        409
      ],
      "type": "conflict",
      "means": "The company has 200 active routines in this mode.",
      "todo": "Delete some; a copy for each user counts too."
    },
    {
      "code": "routine_completed",
      "status": [
        409
      ],
      "type": "conflict",
      "means": "This routine has finished and does not run again.",
      "todo": "Make a new routine."
    },
    {
      "code": "routine_limit_reached",
      "status": [
        409
      ],
      "type": "conflict",
      "means": "This user, or your company's own Bash, has as many active routines as it may.",
      "todo": "Delete or pause one first."
    },
    {
      "code": "routine_name_taken",
      "status": [
        409
      ],
      "type": "conflict",
      "means": "A routine by this name already exists, and the file does not own it.",
      "todo": "Rename one of them."
    },
    {
      "code": "routine_not_linked",
      "status": [
        409
      ],
      "type": "conflict",
      "means": "This routine was not made through the API, so it has no conversation to run in.",
      "todo": "Make the routine with `POST /v1/routines`."
    },
    {
      "code": "routine_paused",
      "status": [
        409
      ],
      "type": "conflict",
      "means": "This routine is paused.",
      "todo": "Resume it with `PATCH /v1/routines/{routine_id}` and `enabled: true`, then run it."
    },
    {
      "code": "screen_control_unavailable",
      "status": [
        409
      ],
      "type": "conflict",
      "means": "Taking control of the screen is not switched on here yet.",
      "todo": "Open the session with `screen: \"view\"`."
    },
    {
      "code": "session_has_no_screen",
      "status": [
        409
      ],
      "type": "conflict",
      "means": "This session was opened without a screen.",
      "todo": "Open one with `screen: \"view\"` or `\"control\"`."
    },
    {
      "code": "session_has_no_voice",
      "status": [
        409
      ],
      "type": "conflict",
      "means": "This session was opened without voice.",
      "todo": "Open one with `voice: true`."
    },
    {
      "code": "shared_change",
      "status": [
        409
      ],
      "type": "conflict",
      "means": "Skills, knowledge and company MCP servers are not versioned yet: every version reads them as they are, so while a deployment runs a version live, a test key or a console developer cannot change them. `deployments` names the live ones.",
      "todo": "Change them with a live key (`vestra deploy --live`), which changes them for your users at once, or as an owner or admin."
    },
    {
      "code": "skill_exists",
      "status": [
        409
      ],
      "type": "conflict",
      "means": "A skill with this slug already exists.",
      "todo": "Upload a new version with `PUT /v1/skills/{skill_id}`, or give a new slug."
    },
    {
      "code": "slug_taken",
      "status": [
        409
      ],
      "type": "conflict",
      "means": "A deployment with this slug already exists.",
      "todo": "Choose another name, or send a `slug`."
    },
    {
      "code": "test_run_failed",
      "status": [
        409
      ],
      "type": "conflict",
      "means": "This version failed its latest test run, so it is not promoted.",
      "todo": "Fix it, run the tests again, then promote."
    },
    {
      "code": "test_run_required",
      "status": [
        409
      ],
      "type": "conflict",
      "means": "This version has no passing test run.",
      "todo": "Run the tests with `POST /v1/deployments/{deployment_id}/test-runs`, then promote."
    },
    {
      "code": "too_many_batches",
      "status": [
        409
      ],
      "type": "conflict",
      "means": "The company already runs as many batches as it may in this mode.",
      "todo": "Wait for one to finish, or cancel one."
    },
    {
      "code": "too_many_scenarios",
      "status": [
        409
      ],
      "type": "conflict",
      "means": "The deployment would hold more test scenarios than it may.",
      "todo": "Remove scenarios made by hand, or declare fewer tests."
    },
    {
      "code": "test_run_in_progress",
      "status": [
        409
      ],
      "type": "conflict",
      "means": "A test run for this version is already running.",
      "todo": "Wait for its verdict with `GET /v1/test-runs/{test_run_id}`."
    },
    {
      "code": "test_runs_busy",
      "status": [
        409
      ],
      "type": "conflict",
      "means": "Too many test runs are running: this company has as many as it may, or we do.",
      "todo": "Try again when one finishes."
    },
    {
      "code": "tool_call_not_pending",
      "status": [
        409
      ],
      "type": "conflict",
      "means": "That call to your tool is not waiting for a result.",
      "todo": "Nothing to do: it was answered, or it expired."
    },
    {
      "code": "user_create_in_progress",
      "status": [
        409
      ],
      "type": "conflict",
      "means": "Another request is making this user right now.",
      "todo": "Retry in a moment."
    },
    {
      "code": "version_never_live",
      "status": [
        409
      ],
      "type": "conflict",
      "means": "That version was never live, so there is nothing to roll back to.",
      "todo": "Promote it instead."
    },
    {
      "code": "version_not_live",
      "status": [
        409
      ],
      "type": "conflict",
      "means": "A live key always runs the live version, so it cannot pin one.",
      "todo": "Drop the `@version`, or pin it with a test key."
    },
    {
      "code": "stream_expired",
      "status": [
        410
      ],
      "type": "invalid_request",
      "means": "The events after that point are no longer kept.",
      "todo": "Read the conversation again with `GET /v1/conversations/{conversation_id}`, and follow its events from now."
    },
    {
      "code": "export_too_large",
      "status": [
        413
      ],
      "type": "invalid_request",
      "means": "This user holds more than an export carries.",
      "todo": "Ask Vestra support for the export."
    },
    {
      "code": "unsupported_media_type",
      "status": [
        415
      ],
      "type": "invalid_request",
      "means": "The body is in a type this route does not read.",
      "todo": "Send JSON with `Content-Type: application/json`, or the type the route names."
    },
    {
      "code": "export_in_progress",
      "status": [
        429
      ],
      "type": "rate_limited",
      "means": "Another export of this user is being built.",
      "todo": "Retry in a minute."
    },
    {
      "code": "rate_limited",
      "status": [
        429
      ],
      "type": "rate_limited",
      "means": "Too many requests.",
      "todo": "Slow down, and retry after the `Retry-After` seconds."
    },
    {
      "code": "routine_fire_budget",
      "status": [
        429
      ],
      "type": "rate_limited",
      "means": "This routine, or this company, has used its runs for this hour.",
      "todo": "Try again later."
    },
    {
      "code": "too_many_in_flight",
      "status": [
        429
      ],
      "type": "rate_limited",
      "means": "Too many requests at once.",
      "todo": "Wait for one to finish, then retry."
    },
    {
      "code": "too_many_streams",
      "status": [
        429
      ],
      "type": "rate_limited",
      "means": "Too many open streams.",
      "todo": "Close one, then retry."
    },
    {
      "code": "voice_busy",
      "status": [
        429
      ],
      "type": "rate_limited",
      "means": "Too many voice calls are open.",
      "todo": "Retry in a minute."
    },
    {
      "code": "warm_limit",
      "status": [
        429
      ],
      "type": "rate_limited",
      "means": "Many computers are already waking for this company.",
      "todo": "Retry in a moment."
    },
    {
      "code": "cancel_failed",
      "status": [
        500
      ],
      "type": "internal",
      "means": "The interaction was not withdrawn.",
      "todo": "Retry the call."
    },
    {
      "code": "internal_error",
      "status": [
        500
      ],
      "type": "internal",
      "means": "Something went wrong on our side.",
      "todo": "Retry. If it keeps happening, send Vestra the `request_id`."
    },
    {
      "code": "mcp_failed",
      "status": [
        500
      ],
      "type": "internal",
      "means": "The MCP request failed on our side.",
      "todo": "Retry it."
    },
    {
      "code": "resolve_failed",
      "status": [
        500
      ],
      "type": "internal",
      "means": "The answer was not recorded.",
      "todo": "Retry the call."
    },
    {
      "code": "not_implemented",
      "status": [
        501
      ],
      "type": "internal",
      "means": "This is not available yet.",
      "todo": "Nothing to do now: the changelog says when it ships."
    },
    {
      "code": "connect_failed",
      "status": [
        502
      ],
      "type": "upstream",
      "means": "The connect link could not be made.",
      "todo": "Retry in a moment."
    },
    {
      "code": "connections_unavailable",
      "status": [
        502
      ],
      "type": "upstream",
      "means": "Connected apps could not be read.",
      "todo": "Retry in a moment."
    },
    {
      "code": "delete_failed",
      "status": [
        502
      ],
      "type": "upstream",
      "means": "The file could not be deleted.",
      "todo": "Try again."
    },
    {
      "code": "deployment_unavailable",
      "status": [
        502
      ],
      "type": "upstream",
      "means": "The deployment could not be read.",
      "todo": "Retry shortly."
    },
    {
      "code": "disconnect_failed",
      "status": [
        502
      ],
      "type": "upstream",
      "means": "The app could not be disconnected.",
      "todo": "Retry in a moment."
    },
    {
      "code": "download_unavailable",
      "status": [
        502
      ],
      "type": "upstream",
      "means": "A download link could not be made.",
      "todo": "Try again."
    },
    {
      "code": "interview_failed",
      "status": [
        502
      ],
      "type": "upstream",
      "means": "The interview stopped before its draft was saved.",
      "todo": "Start again with a description."
    },
    {
      "code": "mcp_auth_required",
      "status": [
        502
      ],
      "type": "upstream",
      "means": "The MCP server asked for credentials it was not given.",
      "todo": "Give the server's credentials as a header with `${secret:NAME}`."
    },
    {
      "code": "mcp_missing_secret",
      "status": [
        502
      ],
      "type": "upstream",
      "means": "The MCP server names secrets that are not stored.",
      "todo": "Store them with `PUT /v1/secrets/{name}`."
    },
    {
      "code": "mcp_unreachable",
      "status": [
        502
      ],
      "type": "upstream",
      "means": "The MCP server did not answer.",
      "todo": "Check that it is up and reachable from the internet, then check it again."
    },
    {
      "code": "mcp_url_not_public",
      "status": [
        502
      ],
      "type": "upstream",
      "means": "The MCP server's address is not public.",
      "todo": "Use an https URL that reaches the public internet."
    },
    {
      "code": "memory_unavailable",
      "status": [
        502
      ],
      "type": "upstream",
      "means": "Memory could not be read or deleted.",
      "todo": "Retry shortly."
    },
    {
      "code": "memory_write_failed",
      "status": [
        502
      ],
      "type": "upstream",
      "means": "The memory could not be saved.",
      "todo": "Retry shortly."
    },
    {
      "code": "navigation_failed",
      "status": [
        502
      ],
      "type": "upstream",
      "means": "The page of a browser fetch could not be opened: the site did not answer, or the address was wrong.",
      "todo": "Check the address, then retry."
    },
    {
      "code": "queue_unavailable",
      "status": [
        502
      ],
      "type": "upstream",
      "means": "Routines are not taking runs right now.",
      "todo": "Try again in a minute."
    },
    {
      "code": "return_unavailable",
      "status": [
        502
      ],
      "type": "upstream",
      "means": "Connect links are not available on this server.",
      "todo": "Contact Vestra support."
    },
    {
      "code": "route_failed",
      "status": [
        502
      ],
      "type": "upstream",
      "means": "A call an MCP tool made inside the API failed.",
      "todo": "Retry it."
    },
    {
      "code": "scenario_generation_failed",
      "status": [
        502
      ],
      "type": "upstream",
      "means": "Tests could not be drafted this time.",
      "todo": "Try again, or write the tests yourself in vestra.yaml."
    },
    {
      "code": "screenshot_failed",
      "status": [
        502
      ],
      "type": "upstream",
      "means": "The browser did not answer with a picture.",
      "todo": "Try again."
    },
    {
      "code": "tool_result_undelivered",
      "status": [
        502
      ],
      "type": "upstream",
      "means": "The result could not reach the work.",
      "todo": "Try again."
    },
    {
      "code": "upload_failed",
      "status": [
        502
      ],
      "type": "upstream",
      "means": "The file could not be stored.",
      "todo": "Try again."
    },
    {
      "code": "user_create_failed",
      "status": [
        502
      ],
      "type": "upstream",
      "means": "The user could not be made.",
      "todo": "Retry the request."
    },
    {
      "code": "voice_connect_failed",
      "status": [
        502
      ],
      "type": "upstream",
      "means": "The call could not be opened.",
      "todo": "Start it again."
    },
    {
      "code": "auth_unavailable",
      "status": [
        503
      ],
      "type": "upstream",
      "means": "We could not check your credentials just now.",
      "todo": "Retry in a few seconds."
    },
    {
      "code": "box_unavailable",
      "status": [
        503
      ],
      "type": "upstream",
      "means": "The user's computer did not wake or did not answer, or its browser is not there to use or is paused while a person pays.",
      "todo": "Retry in a few seconds, or after the payment finishes when the browser is paused for one."
    },
    {
      "code": "database_unavailable",
      "status": [
        503
      ],
      "type": "upstream",
      "means": "We could not reach our database.",
      "todo": "Retry in a few seconds."
    },
    {
      "code": "generator_busy",
      "status": [
        503
      ],
      "type": "upstream",
      "means": "Drafting tests is slow right now.",
      "todo": "Retry after the `Retry-After` seconds."
    },
    {
      "code": "voice_unavailable",
      "status": [
        503
      ],
      "type": "upstream",
      "means": "Voice is not available right now.",
      "todo": "Try again later."
    },
    {
      "code": "timeout",
      "status": [
        504
      ],
      "type": "upstream",
      "means": "A browser fetch's page did not send every capture in time. `partial` holds what it did send.",
      "todo": "Use what `partial` holds, or retry with a longer `timeout_ms`, up to 20000."
    }
  ]
}
